C++ 如何解决;纯虚拟方法称为;
我理解为什么会发生这种情况,但我一直在努力解决它…下面是当我的程序退出时生成错误(从而导致崩溃)时我的代码所做的C++ 如何解决;纯虚拟方法称为;,c++,polymorphism,derived-class,base-class,pure-virtual,C++,Polymorphism,Derived Class,Base Class,Pure Virtual,我理解为什么会发生这种情况,但我一直在努力解决它…下面是当我的程序退出时生成错误(从而导致崩溃)时我的代码所做的 调用的纯虚拟方法 SomeClass::~SomeClass() { BaseClassObject->SomePureVirtualMethod(this); } 我从未调用过newsomeclass,但我有一个QList,我将SomeClass*对象附加到它。SomeClass中此析构函数的作用是告诉DerivedClass从它的QList集合中删除SomeCla
调用的纯虚拟方法
SomeClass::~SomeClass()
{
BaseClassObject->SomePureVirtualMethod(this);
}
我从未调用过
newsomeclass
,但我有一个QList
,我将SomeClass*
对象附加到它。SomeClass
中此析构函数的作用是告诉DerivedClass
从它的QList
集合中删除SomeClass
的特定实例
所以,在一个具体的例子中
BaseClass
=Shape
DerivedClass
=Triangle
SomeClass
=ShapeProperties
拥有对Shape
因此,我从未调用过
newshapeproperties
,但在Triangle
内部有一个QList
。ShapeProperties
中的析构函数是告诉Triangle
从它的QList集合中删除ShapeProperties
的特定属性,调用析构函数时,继承类的析构函数已经被调用。在构造函数和析构函数中,可以有效地将对象的动态类型视为与静态类型相同。也就是说,当您从构造函数/析构函数中调用虚方法时,不会调用它们的重写版本
如果需要在析构函数中调用SomePureVirtualMethod
,则必须在类的析构函数中调用它,在该类中,方法的实际定义是所需的。当调用基类SomeClass
的析构函数中的virtual
方法时,它调用该方法基类SomeClass
的(SomePureVirtualMethod()
),它是一个没有定义的纯虚拟方法。因此会出现错误
为什么会发生这种情况?
构造函数或析构函数中的this
的类型是调用其构造函数或析构函数的类型,因此动态分派在构造函数和析构函数中不起作用,正如您希望它在所有其他函数中起作用一样
为什么会崩溃?
因为从构造函数或析构函数调用纯虚函数是一种未定义的行为
C++03 10.4/6状态
“成员函数可以从抽象类的构造函数(或析构函数)调用;直接或间接地对纯虚拟函数进行虚拟调用(10.3)对从此类构造函数(或析构函数)创建(或销毁)的对象的影响尚未定义。”
如何避免它?
只需确保不要从构造函数或析构函数调用纯虚函数。
除非您了解所涉及的动态,否则不要调用构造函数或析构函数中的virtual
方法。可能发生这种情况的另一个原因是,这取决于您的编译器和系统,并且来自悬挂引用。释放内存的可能状态:
- 内存可能被标记为已解除分配
- 内存可能被故意扰乱
- 内存可能会被重用
- 这段记忆可能就这样留下了
最后一个是一个有趣的例子。物体“到底是什么样子的?”
在本例中,它是抽象基类的一个实例;
当然,这就是vtbl留下的方式。如果我们尝试
为这样的对象调用纯虚拟成员函数
“纯虚拟函数调用”
那么,如果我在派生构造函数中使用调用它,我怎么知道我指的是this
的哪个实例呢?我可能误解了这一点,“如果需要在析构函数中调用某个pureVirtualMethod
,那么你必须在类的析构函数中调用它,而你想要的方法的实际定义就是这个类的析构函数。”@user869525:简单地说,从析构函数调用SomePureVirtualMethod
不会解析为最派生的重写。如果要调用最派生的重写,必须从实现此类重写的类的析构函数调用它。是的,我理解这一点,但它无法解决我的问题,因为我在Some中类
,而不是基类
或派生类
拥有基类
的实例,而派生类
拥有某类
的列表
。某类
中的析构函数需要从列表
中删除某类
的实例属于DerivedClass
。
void DerivedClass::SomePureVirtualMethod(SomeClass* obj)
{
//Do stuff to remove obj from a collection
}