【发布时间】:2020-01-18 05:32:40
【问题描述】:
我在这里读过这篇文章:When to use virtual destructors?
我的想法是,每当我们使用new 或智能指针动态创建对象时,基类应该有一个适当的virtual 析构函数,用于在删除时销毁对象。
然后我发现了一些类似下面的代码(简化形式),它错过了Base中的virtual析构函数:
class Base
{
public:
// some static members
};
class Derived1 final : public Base
{
public:
// other members
// default constructor does not construct the `Base` in constructor member intilizer
Derived1() {};
virtual ~Derived1() = default;
};
class Derived2 final : public Base
{
public:
// other members
Derived2() {}; // default constructor does not construct the `Base`
~Derived2() = default;
};
int main()
{
// creating Derived1 dynamically // 1
Derived1 *d1Object = new Derived1{};
// creating Derived2 dynamically // 2
Derived2 *d2Object1 = new Derived2{};
// creating Derived2 statically // 3
Derived2 d2Object2{};
// clean up
delete d1Object;
delete d2Object1;
}
我的问题是:
- 在任何情况下我是否有未定义的行为(
1, 2, 3)?为什么? - 在两个派生类的构造函数的成员初始化器列表中构造
Base不是必需的(在上述特定情况下)?
我正在使用 C++11。
【问题讨论】:
-
使用指向具有非虚拟析构函数的基类的指针删除派生类对象会导致未定义的行为。由于您的指针不是指向具有非虚拟析构函数的基类,因此我认为您在这里避免了 UB。
-
除了已经给出的答案之外,您不需要将
Derived1的析构函数声明为virtual,因为Derived1是final(因此永远不会被继承)。
标签: c++ class c++11 polymorphism virtual