default virtual d'tor

2019-02-21 19:06发布

问题:

Let us assume I have two classes:

class Base{};

class Derived: public Base{};

none has d'tor, in this case if I declare about variables:

Base b;
Derived d;

my compiler will produce for me d'tors, my question is, the default d'tors of the b and d will be virtual or not?

回答1:

my question is, the d'tors of the b and d will be virtual or not

No, they won't. If you want a virtual destructor, you will have to define your own, even if its implementation is exactly the same as that which would be supplied by the compiler:

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


回答2:

The destructors of Base and Derived will not be virtual. To make a virtual destructor you need to mark it up explicitly:

struct Base
{
    virtual ~Base() {}
};

Actually there's now only one reason to use virtual destructors. That is to shut up the gcc warning: "class 'Base' has virtual functions but non-virtual destructor". As long as you always store your allocated objects in a shared_ptr, then you really don't need a virtual destructor. Here's how:

#include <iostream>   // cout, endl
#include <memory>     // shared_ptr
#include <string>     // string

struct Base
{
   virtual std::string GetName() const = 0;
};

class Concrete : public Base
{
   std::string GetName() const
   {
      return "Concrete";
   }
};

int main()
{
   std::shared_ptr<Base> b(new Concrete);
   std::cout << b->GetName() << std::endl;
}

The shared_ptr will clean up correctly, without the need for a virtual destructor. Remember, you will need to use the shared_ptr though!

Good luck!



回答3:

my question is, the d'tors of the b and d will be virtual or not

Short answer : Nopes!



回答4:

They will NOT be virtual.However, if you declared(and defined) a virtual dtor in Base, then the derived's dtor would be automatically virtual. HTH.



回答5:

How can they be virtual unless you explicitly make them as virtual



回答6:

Just to add one more example to Daniel Lidström's answer

As long as you always store your allocated objects in a shared_ptr, then you really don't need a virtual destructor.

If one uses a shared_ptr like this:

    std::shared_ptr<Base> b(new Concrete);

Then the Concrete destructor and the Base destructor are called on destruction of the object.

If one uses a shared_ptr like this:

Base* pBase = new Concrete;
std::shared_ptr<Base> b(pBase);

Then only the Base destructor is called on destruction of the object.

This is an example

#include <iostream>   // cout, endl
#include <memory>     // shared_ptr
#include <string>     // string

struct Base
{
   virtual std::string GetName() const = 0;
   ~Base() { std::cout << "~Base\n"; } 
};

struct Concrete : public Base
{
   std::string GetName() const
   {
      return "Concrete";
   }
   ~Concrete() { std::cout << "~Concrete\n"; } 
};

int main()
{
  {
    std::cout << "test 1\n";
    std::shared_ptr<Base> b(new Concrete);
    std::cout << b->GetName() << std::endl;
  }

  {
    std::cout << "test 2\n";
    Base* pBase = new Concrete;
    std::shared_ptr<Base> b(pBase);
    std::cout << b->GetName() << std::endl;
  }

}