隐式声明的析构函数
Implicitly declared destructor
如果我是正确的,默认析构函数总是隐式声明的,除非用户声明它。根据 cppreference:
Deleting an object through pointer to base invokes undefined behavior unless the destructor in the base class is virtual
现在,考虑这个例子:
struct B {};
struct D : B {};
隐式声明的析构函数B::~B()
是虚拟的吗?如果不是,我是否应该在使用继承时始终声明一个虚拟析构函数?
Is the implicitly declared destructor B::~B() virtual?
否,根据 class.dtor/3:
An implicitly-declared prospective destructor for a class X will have
the form
~X()
当然,根据 class.dtor/12:
If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual
If not, should I always declare a virtual destructor when using inheritance?
C++ 核心指南,C.35 建议将 public 的基础 class 析构函数设为虚拟:
C.35: A base class destructor should be either public and virtual, or protected and non-virtual
Reason To prevent undefined behavior. If the destructor is public, then calling code can attempt to destroy a derived class object
through a base class pointer, and the result is undefined if the base
class’s destructor is non-virtual. If the destructor is protected,
then calling code cannot destroy through a base class pointer and the
destructor does not need to be virtual; it does need to be protected,
not private, so that derived destructors can invoke it. In general,
the writer of a base class does not know the appropriate action to be
done upon destruction.
[...]
Note A virtual function defines an interface to derived classes that can be used without looking at the derived classes. If the
interface allows destroying, it should be safe to do so.
[...]
Exception We can imagine one case where you could want a protected virtual destructor: When an object of a derived type (and only of such
a type) should be allowed to destroy another object (not itself)
through a pointer to base. We haven’t seen such a case in practice,
though.
Enforcement
- A class with any virtual functions should have a destructor that is either public and virtual or else protected and non-virtual.
如果我是正确的,默认析构函数总是隐式声明的,除非用户声明它。根据 cppreference:
Deleting an object through pointer to base invokes undefined behavior unless the destructor in the base class is virtual
现在,考虑这个例子:
struct B {};
struct D : B {};
隐式声明的析构函数B::~B()
是虚拟的吗?如果不是,我是否应该在使用继承时始终声明一个虚拟析构函数?
Is the implicitly declared destructor B::~B() virtual?
否,根据 class.dtor/3:
An implicitly-declared prospective destructor for a class X will have the form
~X()
当然,根据 class.dtor/12:
If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual
If not, should I always declare a virtual destructor when using inheritance?
C++ 核心指南,C.35 建议将 public 的基础 class 析构函数设为虚拟:
C.35: A base class destructor should be either public and virtual, or protected and non-virtual
Reason To prevent undefined behavior. If the destructor is public, then calling code can attempt to destroy a derived class object through a base class pointer, and the result is undefined if the base class’s destructor is non-virtual. If the destructor is protected, then calling code cannot destroy through a base class pointer and the destructor does not need to be virtual; it does need to be protected, not private, so that derived destructors can invoke it. In general, the writer of a base class does not know the appropriate action to be done upon destruction.
[...]
Note A virtual function defines an interface to derived classes that can be used without looking at the derived classes. If the interface allows destroying, it should be safe to do so.
[...]
Exception We can imagine one case where you could want a protected virtual destructor: When an object of a derived type (and only of such a type) should be allowed to destroy another object (not itself) through a pointer to base. We haven’t seen such a case in practice, though.
Enforcement
- A class with any virtual functions should have a destructor that is either public and virtual or else protected and non-virtual.