[英]How to resolve “pure virtual method called”
我明白为什么会发生这种情况,但我一直在努力解决它......这是我的代码在我的程序退出时生成错误(从而导致崩溃)时所做的事情......
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
从它的QList<SomeClass*>
集合中删除SomeClass
的特定实例。
所以,在一个具体的例子中......
BaseClass
= Shape
DerivedClass
= Triangle
SomeClass
= ShapeProperties
拥有对Shape
的引用
所以,我从来没有打电话给new ShapeProperties
但是我在Triangle
里面有一个QList<ShapeProperties*>
。 ShapeProperties
的析构ShapeProperties
是告诉Triangle
从它的QList<ShapeProperties*>
集合中删除ShapeProperties
的特定属性。
当你的析构函数被调用时,继承类的析构函数已经被调用。 在构造函数和析构函数中,对象的动态类型可以有效地被认为与静态类型相同。 也就是说,当您从构造函数/析构函数中调用虚拟方法时,调用的不是它们的覆盖版本。
如果需要在析构函数中调用SomePureVirtualMethod
,则必须在所需方法的实际定义所在的类的析构函数中调用它。
当调用virtual
方法在基类的析构函数SomeClass
调用(方法SomePureVirtualMethod()
的基类SomeClass
是没有定义的纯虚方法。 因此错误。
为什么会发生这种情况?
构造函数或析构函数中的this
类型是其构造函数或析构函数被调用的类型,因此动态分派在构造函数和析构函数中不起作用,因为您期望它在所有其他函数中起作用。
为什么会崩溃?
因为从构造函数或析构函数调用纯虚函数是一种未定义的行为。
C++03 10.4/6 状态
“可以从抽象类的构造函数(或析构函数)调用成员函数;对于从这样的构造函数创建(或销毁)的对象,直接或间接对纯虚函数进行虚调用(10.3)的效果(或析构函数)未定义。”
如何避免?
只要确保您不从构造函数或析构函数调用纯虚函数即可。
除非您了解所涉及的动态,否则不要在构造函数或析构函数中调用virtual
方法。
根据您的编译器和系统,这可能发生的另一个原因是悬空引用。 Paul SR Chisholm 解释了释放内存的可能状态:
- 内存可能被标记为已释放。
- 记忆可能被故意打乱。
- 内存可能会被重用。
- 记忆可能完全保持原样。
最后是一个有趣的案例。 什么是“原样”的对象? 在这种情况下,它是抽象基类的一个实例; 当然这就是 vtbl 留下的方式。 如果我们尝试为这样的对象调用纯虚成员函数会发生什么?
“调用的纯虚函数”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.