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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10707286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:21:52  来源:igfitidea点击:

How to resolve "pure virtual method called"

c++polymorphismderived-classbase-classpure-virtual

提问by user869525

I understand why this is happening, but I'm stuck trying to resolve it...here is what my code is doing when the error is generated (thus, leading to a crash) when my program exits...

我明白为什么会发生这种情况,但我一直在努力解决它......这是我的代码在我的程序退出时生成错误(从而导致崩溃)时所做的事情......

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
}

I never have a call to new SomeClassbut I have a QList<SomeClass*>which I append SomeClass*objects to. The purpose of this destructor in SomeClassis to tell DerivedClassto remove a specific instance of SomeClassfrom it's collection of QList<SomeClass*>.

我从来没有打电话给,new SomeClass但我有一个QList<SomeClass*>我将SomeClass*对象附加到的。这个析构函数 in 的目的SomeClass是告诉从它的集合中DerivedClass删除一个特定的实例。SomeClassQList<SomeClass*>

So, in a concrete example...

所以,在一个具体的例子中......

BaseClass= Shape

BaseClass= Shape

DerivedClass= Triangle

DerivedClass= Triangle

SomeClass= ShapePropertieswhich owns a reference to Shape

SomeClass=ShapeProperties拥有对Shape

So, I never have a call to new ShapePropertiesbut I have a QList<ShapeProperties*>inside of Triangle. The destructor in ShapePropertiesis to tell Triangleto remove a specific property of ShapePropertiesfrom it's collection of QList<ShapeProperties*>.

所以,我从来没有打电话new ShapeProperties,但是我有一个QList<ShapeProperties*>里面Triangle。in 的析构函数ShapeProperties是告诉从它的集合中Triangle删除特定的属性。ShapePropertiesQList<ShapeProperties*>

回答by K-ballo

By the time your destructor is called, the destructor of inherited classes has already been called. Within constructors and destructors, the dynamic type of the object can effectively be considered to be the same as the static type. That is, when you call virtual methods from within your constructors/destructors it's not the overriden versions of them that are called.

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

If SomePureVirtualMethodneeds to be called at the destructor, then you will have to call it within the destructor of the class where the actual definition of the method you want is.

如果SomePureVirtualMethod需要在析构函数中调用,则必须在所需方法的实际定义所在的类的析构函数中调用它。

回答by Alok Save

When you call the virtualmethod in the destructor of the Base class SomeClassit calls the method(SomePureVirtualMethod()) of the Base class SomeClasswhich is a pure virtual method with no definition. And hence the error.

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

Why does this happen?
The type of thisin constructor or destructor is of the type whose constructor or destructor is being called and hence dynamic dispatch doesn't work in constructors and destructors as you would expect it to work in all other functions.

为什么会发生这种情况?
该类型this的构造函数和析构函数是它的构造和析构函数被调用,因此动态调度在构造函数和析构函数不工作,你会期待它工作的所有其他功能的类型。

Why does it crash?
Because calling a pure virtual function from constructor or destructor is an Undefined Behavior.

为什么会崩溃?
因为从构造函数或析构函数调用纯虚函数是一种未定义的行为

C++03 10.4/6 states

C++03 10.4/6 状态

"Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined."

“可以从抽象类的构造函数(或析构函数)调用成员函数;对于从这样的构造函数创建(或销毁)的对象,直接或间接对纯虚函数进行虚调用(10.3)的效​​果(或析构函数)未定义。”

How to avoid it?
Just ensure that you don't call a pure virtual function from constructor or destructor.
Don't call virtualmethods in constructor or destructor unless you understand the dynamics involved.

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