2012-05-22 138 views
17

我明白为什么发生这种情况,但我坚持试图解决它“纯称为虚拟方法” ......这里是产生错误时,我的代码做什么(因此,导致崩溃)我的程序退出时...如何解决

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但我有一个QList<ShapeProperties*>TriangleShapeProperties中的析构函数是告诉Triangle从它的QList<ShapeProperties*>集合中删除ShapeProperties的特定属性。

回答

28

通过您的析构函数被调用的时候,继承类的析构函数已经被调用。在构造函数和析构函数中,对象的动态类型可以被有效地视为与静态类型相同。也就是说,当你从构造函数/析构函数中调用虚拟方法时,它并不是被调用的被覆盖的版本。

如果需要在析构函数处调用SomePureVirtualMethod,那么您必须在类的析构函数中调用它,在此类中实际定义您想要的方法。

+0

那么我如何知道在引用的构造函数中调用了哪个'this'实例? – user869525

+0

@ user869525:你可以尝试改说吗?我不明白... –

+0

我可能误解了这个,“如果'SomePureVirtualMethod'需要在析构函数中调用,那么你必须在类的析构函数中调用它,在那里实际定义你想要的方法。 “ – user869525

8

当调用在Base类SomeClass的析构函数的virtual方法它调用基类SomeClass的方法(SomePureVirtualMethod()),这是没有定义纯虚方法。因此错误。

这是为什么发生?
构造函数或析构函数中的this的类型是其构造函数或析构函数被调用的类型,因此动态调度在构造函数和析构函数中不起作用,因为它可以在所有其他函数中使用。

为什么它会崩溃?
由于呼叫从构造或析构纯虚函数是一个未定义行为

C++ 03 10。4/6状态

“成员函数可以从一个抽象类的构造(或析构函数)被调用;直接或间接地使虚拟呼叫(10.3),以纯虚函数为对象的效果从这样的构造函数(或析构函数)创建(或销毁)是未定义的。“

如何避免它?
只要确保不要从构造函数或析构函数调用纯虚函数。
除非您了解所涉及的动态,否则不要在构造函数或析构函数中调用virtual方法。