类内的纯虚拟析构函数定义给出编译错误
基类中的纯虚拟析构函数
应该有一个定义。否则,编译器将在链接时从派生类析构函数生成对基类析构函数的调用,并导致链接错误。
我尝试在基类中定义纯虚拟析构函数,如下所示:
class base
{
public:
base()
{
cout << "constructor in base class\n";
}
virtual ~base()=0
{}
};
这给出了编译错误:
错误:函数定义上的纯说明符
然后我尝试在基类之外定义函数,如下所示:
class base
{
public:
base()
{
cout << "constructor in base class\n";
}
virtual ~base()=0;
};
base::~base()
{
}
这消除了编译错误,并且其行为符合我的理解。
但我的问题是如何在基类之外定义纯虚拟析构函数来消除编译错误?
The pure virtual destructor
in base class should have a definition. Otherwise compiler will generate a call to base class destructor from the derived class destructor during link-time and will cause a link-error.
I tried to define the pure virtual destructor inside the base class like below:
class base
{
public:
base()
{
cout << "constructor in base class\n";
}
virtual ~base()=0
{}
};
This gave the compilation error:
error: pure-specifier on function-definition
Then i tried to define the function outside the base class like below:
class base
{
public:
base()
{
cout << "constructor in base class\n";
}
virtual ~base()=0;
};
base::~base()
{
}
This removes the compilation error and it behaves as my understanding.
But my question is how does defining the pure virtual destructor outside the base class removes the compilation error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你的第二个例子是正确的。
许多其他答案都认为使用默认实现的纯虚函数是非法的,但这是不正确的。
对于纯虚拟析构函数,您必须有一个定义(请参阅 xmoex 答案中的链接)。
确实如此:
但是,正如您所注意到的,可以在声明之外提供定义。
Your second example is correct.
A lot of the other answers assume that it is illegal to have a pure virtual function with a default implementation, however that is incorrect.
In the case of a pure virtual destructor you must have a definition (see the link in xmoex answer).
It is true that:
However, as you noticed it possible to provide a definition outside of the declaration.
我查看了此页面:
http://www.gotw.ca/gotw/031.htm
并从我的理解纯虚拟析构函数必须有一个定义(即使是空的),因为每个派生类都必须调用基类析构函数
i looked at this page:
http://www.gotw.ca/gotw/031.htm
and from my understanding a pure virtual destructor must have a definition (even an empty one) as every derived class has to call the base classes destructor
编写以下语法是无效的:
如果要提供纯虚拟成员函数的实现,则应该在类之外进行。大多数时候你不应该这样做,因为无论如何都不应该调用纯虚函数。然而,可以定义纯虚函数的实现。
事实上,一个纯虚析构函数必须有一个实现。这是因为无论给定类中的析构函数是否是纯虚拟的,在对象销毁时都会调用所有基类的析构函数。
因此,如果您创建从
base
派生的任何类的实例,那么在某个时刻,将调用该对象所属的所有类的析构函数,包括base::~base()析构函数。如果您不定义它,链接器将找不到所需的符号并会抱怨。
It is invalid syntax to write:
If you want to supply implementation of a pure virtual member function, you should do it outside of the class. Most of the time you should not do this, since pure virtual functions should never be called anyhow. It is however possible to define implementation for pure virtual functions.
In fact, a pure virtual destructor must have an implementation. This is because destructors of all base classes are called on object destruction regardless of whether destructor in a given class is pure virtual or not.
Thus, if you create an instance of any of the classes derived from
base
then at some point destructors of all classes to which the object belongs will be called including thebase::~base()
destructor. If you do not define it, the linker will not find a required symbol and will complain.析构函数是唯一的方法,即使它是纯虚拟的,也必须有一个实现才能使定义它的类有用。因此,与 @Kiril 的答案相反,我想说纯虚函数可以有实现。
有点题外话:
The destructor is the only method that even if it is pure virtual, has to have an implementation in order for the class it's defined in to be useful. So in contrast to @Kiril's answer I would say that pure virtual functions can have implementations.
Somewhat off topic :
纯虚拟方法可以有实现,但它们使基类抽象并强制派生类覆盖这些方法。
假设基类中有一个指针成员。您想在析构函数中删除它,但同时也使该类抽象 - 因此您可以实现纯虚拟析构函数。
这是一个实现细节 - 析构函数的实现这一事实不应该从外部可见。
Pure virtual methods can have implementations, but they make the base class abstract and force deriving classes to overwrite those methods.
Say you have a pointer member in the base class. You want to delete it on the destructor but also make the class abstract - so you implement to pure virtual destructor.
This is an implementation detail - the fact that the destructor is implemented should't be visible from the outside.