繁体   English   中英

如何解决“调用的纯虚方法”

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM