如何解决“纯虚方法”

时间:2012-05-22 17:49:25

标签: c++ polymorphism derived-class base-class pure-virtual

我理解为什么会发生这种情况,但我一直试图解决它...这是我的代码在我的程序退出时生成错误(因此导致崩溃)时所做的事情...... / 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中此析构函数的目的是告诉DerivedClassSomeClass的集合中删除QList<SomeClass*>的特定实例。

所以,具体的例子......

BaseClass = Shape

DerivedClass = Triangle

SomeClass = ShapeProperties拥有对Shape

的引用

所以,我从来没有打电话给new ShapeProperties,但我在QList<ShapeProperties*>内有一个TriangleShapeProperties中的析构函数是告诉TriangleShapeProperties的集合中删除QList<ShapeProperties*>的特定属性。

3 个答案:

答案 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留下的方式。如果我们尝试 为此类对象调用纯虚拟成员函数?

“调用了纯虚函数”。