我理解为什么会发生这种情况,但我一直试图解决它...这是我的代码在我的程序退出时生成错误(因此导致崩溃)时所做的事情...... / p>
pure virtual method called
SomeClass::~SomeClass()
{
BaseClassObject->SomePureVirtualMethod(this);
}
void DerivedClass::SomePureVirtualMethod(SomeClass* obj)
{
//Do stuff to remove obj from a collection
}
我从未接到new SomeClass
的电话,但我有QList<SomeClass*>
我追加SomeClass*
个对象。 SomeClass
中此析构函数的目的是告诉DerivedClass
从SomeClass
的集合中删除QList<SomeClass*>
的特定实例。
所以,具体的例子......
BaseClass
= Shape
DerivedClass
= Triangle
SomeClass
= ShapeProperties
拥有对Shape
所以,我从来没有打电话给new ShapeProperties
,但我在QList<ShapeProperties*>
内有一个Triangle
。 ShapeProperties
中的析构函数是告诉Triangle
从ShapeProperties
的集合中删除QList<ShapeProperties*>
的特定属性。
答案 0 :(得分:29)
当你的析构函数被调用时,已经调用了继承类的析构函数。在构造函数和析构函数中,对象的动态类型可以有效地被认为与静态类型相同。也就是说,当你从构造函数/析构函数中调用虚方法时,它不是被调用它们的覆盖版本。
如果需要在析构函数中调用SomePureVirtualMethod
,那么你必须在类的析构函数中调用它,在那里你需要实际的方法定义。
答案 1 :(得分:9)
当您在Base类virtual
的析构函数中调用SomeClass
方法时,它会调用基类SomePureVirtualMethod()
的方法(SomeClass
),这是纯虚拟的方法没有定义。因而错误。
为什么会这样?
构造函数或析构函数中this
的类型是其构造函数或析构函数被调用的类型,因此动态调度在构造函数和析构函数中不起作用,因为您希望它在所有其他函数中起作用。
为什么会崩溃?
因为从构造函数或析构函数调用纯虚函数是未定义行为。
C ++ 03 10.4 / 6州
“可以从抽象类的构造函数(或析构函数)调用成员函数;对于正在创建(或销毁)的对象,直接或间接地对纯虚函数进行虚拟调用(10.3)的效果构造函数(或析构函数)未定义。“
如何避免?
只需确保不要从构造函数或析构函数中调用纯虚函数
除非您了解所涉及的动态,否则不要在构造函数或析构函数中调用virtual
方法。
答案 2 :(得分:0)
还有另一个原因可能会发生这种情况,具体取决于您的编译器和系统,该原因来自悬而未决的参考。 Paul S. R. Chisholm explains释放内存的可能状态:
- 该内存可能被标记为已释放。
- 内存可能被故意打乱了。
- 内存可能会被重用。
- 内存可能已经完全保留了。
最后一个有趣的案例。对象到底是什么 它是“?”在这种情况下,它是抽象基类的实例; 当然,这就是vtbl留下的方式。如果我们尝试 为此类对象调用纯虚拟成员函数?
“调用了纯虚函数”。