Usi*_*Cpp 1 c++ polymorphism virtual class c++11
我在这里阅读了这篇文章:什么时候使用虚拟析构函数?
我的想法是,每当我们使用动态new指针或智能指针动态创建对象时,基类都应具有适当的virtual析构函数,以在删除对象时对其进行破坏。
然后,我发现了一些如下代码(简化形式),它错过了virtual析构函数Base:
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;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
1, 2, 3),我都有未定义的行为吗?为什么?Base在两个派生类的构造函数的成员初始化器列表中构造,不是必需的(在上述特定情况下)?我正在使用C ++ 11。
该代码中的对象指针实际上不是多态的:的静态类型与*d1Object动态类型Derived1&相同,即(其他对象也是如此)。
因此,销毁它会直接调用正确的析构函数~Derived1。因此,一切都很好。以下代码中出现问题:
Base* b = new Derived1();
delete b;
Run Code Online (Sandbox Code Playgroud)
这隐式调用b->~Base();。而且,由于~Base不是虚拟的,~Derived1并没有被调用,你因此得到UB。
的情况也是如此std::unique_ptr<Base>。但是,这不是正确的,std::shared_ptr<Base>因为shared_ptr<>构造函数是模板化的,并存储与其一起构造的实际对象的析构函数。也就是说,以下方法很好,并且可以为两个对象调用正确的析构函数:
std::shared_ptr<Base> p1{new Derived1{});
std::shared_ptr<Base> p2 = std::make_shared<Derived1>();
Run Code Online (Sandbox Code Playgroud)
至于关于构造函数的问题,与数据成员的观点相同:即使缺少初始化程序列表中的数据,它们仍将按照其声明的顺序进行默认初始化,对于基类,则按照大多数情况的顺序进行初始化。距离最近的父母较远。换句话说,您不能初始化父类,它总是会发生。
| 归档时间: |
|
| 查看次数: |
107 次 |
| 最近记录: |