по умолчанию виртуальный д'тор - PullRequest
9 голосов
/ 10 октября 2010

Предположим, у меня есть два класса:

class Base{};

class Derived: public Base{};

ни один не имеет d'tor, в этом случае, если я объявлю о переменных:

Base b;
Derived d;

мой компилятор выдаст для меняd'ors, мой вопрос, d'ors по умолчанию b and d будет виртуальным или нет?

Ответы [ 6 ]

10 голосов
/ 10 октября 2010

мой вопрос: d'ors of b и d будут виртуальными или нет

Нет, они не будут. Если вам нужен виртуальный деструктор, вам придется определить свой собственный, даже если его реализация точно такая же, как та, которая будет предоставлена ​​компилятором:

class Base {
  public:
    virtual ~Base() {}
};
7 голосов
/ 10 октября 2010

Деструкторы Base и Derived не будут virtual.Чтобы создать деструктор virtual, вам нужно явно пометить его:

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

На самом деле теперь есть только одна причина использовать виртуальные деструкторы.Это значит отключить предупреждение gcc: «класс« Base »имеет виртуальные функции, но не виртуальный деструктор».Пока вы всегда храните свои выделенные объекты в shared_ptr, вам действительно не нужен виртуальный деструктор.Вот как это делается:

#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;
}

shared_ptr будет корректно очищаться без использования виртуального деструктора.Помните, что потребуется использовать shared_ptr, хотя!

Удачи!

5 голосов
/ 10 октября 2010

мой вопрос: d'ors of b и d будут виртуальными или нет

Краткий ответ: Нет!

3 голосов
/ 10 октября 2010

Они НЕ будут виртуальными. Однако, если вы объявите (и определили) виртуальный dtor в Base, тогда производный dtor будет автоматически виртуальным. НТН.

2 голосов
/ 10 октября 2010

Как они могут быть виртуальными, если вы явно не сделаете их виртуальными

1 голос
/ 24 мая 2013

Просто чтобы добавить еще один пример к ответу Даниэля Лидстрёма

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

Если кто-то использует shared_ptr, например:

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

Затем Бетонный деструктор и Базовый деструктор вызываются при уничтожении объекта.

Если кто-то использует shared_ptr, например:

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

Тогда только Деструктор базы вызывается при уничтоженииобъект.

Это пример

#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;
  }

}
...