Default virtual d'tor
Предположим, что у меня есть два класса:
class Base{};
class Derived: public Base{};
none имеет d'tor, в этом случае, если я объявляю о переменных:
Base b;
Derived d;
Мой компилятор создаст для меня dors, мой вопрос, по умолчанию dors of b and d
будет виртуальным или нет?
Ответы
Ответ 1
мой вопрос в том, что д'орты b и d будут виртуальными или нет
Нет, они не будут. Если вам нужен виртуальный деструктор, вам придется определить свой собственный, даже если его реализация точно такая же, как и тот, который будет предоставлен компилятором:
class Base {
public:
virtual ~Base() {}
};
Ответ 2
Деструкторы 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
хотя!
Удачи!
Ответ 3
мой вопрос в том, что д'орты b и d будут виртуальными или нет
Короткий ответ: Nopes!
Ответ 4
Они НЕ будут виртуальными. Однако, если вы объявили (и определили) виртуальный dtor в Base, тогда производный dtor будет автоматически виртуальным. НТН.
Ответ 5
Как они могут быть виртуальными, если вы явно не сделаете их виртуальными
Ответ 6
Просто добавьте еще один пример в ответ Даниэля Лидстрема
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;
}
}