类内的纯虚拟析构函数定义给出编译错误

发布于 2024-12-16 19:48:08 字数 629 浏览 2 评论 0原文

基类中的纯虚拟析构函数应该有一个定义。否则,编译器将在链接时从派生类析构函数生成对基类析构函数的调用,并导致链接错误。

我尝试在基类中定义纯虚拟析构函数,如下所示:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

Saygoodbye 2024-12-23 19:48:08

你的第二个例子是正确的。

许多其他答案都认为使用默认实现的纯虚函数是非法的,但这是不正确的。

对于纯虚拟析构函数,您必须有一个定义(请参阅 xmoex 答案中的链接)。

确实如此:

§10.4/2 函数声明不能​​同时提供纯说明符
和定义

但是,正如您所注意到的,可以在声明之外提供定义。

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:

§10.4/2 a function declaration cannot provide both a pure-specifier
and a definition

However, as you noticed it possible to provide a definition outside of the declaration.

桃扇骨 2024-12-23 19:48:08

我查看了此页面:

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

把梦留给海 2024-12-23 19:48:08

编写以下语法是无效的:

virtual ~base()=0
{}

如果要提供纯虚拟成员函数的实现,则应该在类之外进行。大多数时候你不应该这样做,因为无论如何都不应该调用纯虚函数。然而,可以定义纯虚函数的实现。

事实上,一个纯虚析构函数必须有一个实现。这是因为无论给定类中的析构函数是否是纯虚拟的,在对象销毁时都会调用所有基类的析构函数。

因此,如果您创建从 base 派生的任何类的实例,那么在某个时刻,将调用该对象所属的所有类的析构函数,包括 base::~base()析构函数。如果您不定义它,链接器将找不到所需的符号并会抱怨。

It is invalid syntax to write:

virtual ~base()=0
{}

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 the base::~base() destructor. If you do not define it, the linker will not find a required symbol and will complain.

瀞厅☆埖开 2024-12-23 19:48:08

析构函数是唯一的方法,即使它是纯虚拟的,也必须有一个实现才能使定义它的类有用。因此,与 @Kiril 的答案相反,我想说纯虚函数可以有实现。

有点题外话:

struct base {
    virtual void func() = 0;
};

void base::func() { /* default implementation */ }

class derived : public base{
    void func() { base::func(); } // have to explicitly call default implementation.
};

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 :

struct base {
    virtual void func() = 0;
};

void base::func() { /* default implementation */ }

class derived : public base{
    void func() { base::func(); } // have to explicitly call default implementation.
};
谜泪 2024-12-23 19:48:08

纯虚拟方法可以有实现,但它们使基类抽象并强制派生类覆盖这些方法。

假设基类中有一个指针成员。您想在析构函数中删除它,但同时也使该类抽象 - 因此您可以实现纯虚拟析构函数。

这是一个实现细节 - 析构函数的实现这一事实不应该从外部可见。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文