Why a pure virtual destructor needs an implementat

2020-02-28 05:22发布

I know the cases where pure virtual destructors are needed. I also know that If we don't provide an implementation for them it will give me a linker error. What I don't understand is why this should be the case in a code fragment as shown below:

int main()
{
    Base * p = new Derived;
}

Here there is no delete, so no call to destructor and so no need for its implementation(assuming it is supposed to behave like other normal functions which are declared but not defined, linker complains only when we call them)...or am I missing something?

I need to understand why this should be a special case?

Edit: based on comments from BoBTFish

Here are my Base and Derived classes

class Base
{
public:
    Base(){}
    virtual ~Base() = 0;
};

class Derived : public Base
{
};

3条回答
狗以群分
2楼-- · 2020-02-28 05:34

The compiler tries to build the virtual table given a virtual (pure or not) destructor, and it complains because it can't find the implementation.

virtual destructors differ from other virtual functions because they are called when the object is destroyed, regardless of whether it was implemented or not. This requires the compiler to add it to the vf table, even if it's not called explicitly, because the derived class destructor needs it.

Pedantically, the standard requires a pure virtual destructor to be implemented.

查看更多
女痞
3楼-- · 2020-02-28 05:48

C++11 standard:

12.4 Destructors

Paragraph 9:

A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined. If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.
查看更多
Root(大扎)
4楼-- · 2020-02-28 05:49

Destructors differ from other virtual functions in this way, because they are special and automatically invoked in bases, with no possible, useful or meaningful way to prevent it.

[C++11: 12.4/9]: A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined. If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.

Bases are always destroyed, and to do this, a base destructor definition is required. Conversely, other overridden virtual functions are not invoked automatically at all. Hence the special-case requirement.

struct Base
{
   virtual ~Base()    = 0;  // invoked no matter what
   virtual void foo() = 0;  // only invoked if `Base::foo()` is called
};

Base::~Base() {}
/* void Base::foo() {} */

struct Derived : Base
{
   virtual void foo() { /* Base::foo(); */ }
};

int main()
{
    std::unique_ptr<Base> ptr(new Derived());
}
查看更多
登录 后发表回答