用不完整类型破坏对象

时间:2016-08-22 14:26:46

标签: c++

我已经阅读了关于这个主题的其他stackoverflow问题,但我真的对不完整的类型和这个C ++规范段落§5.3.5/ 5感到困惑:

  

如果要删除的对象的类型不完整   删除和完整的类有一个非平凡的析构函数或   解除分配函数,行为未定义。

举个例子,.h:

class Holder::Impl {};
Holder::Holder() : _mptr(new Impl) {}
Holder::~Holder() {}

的.cpp

{{1}}

类Holder的非内联析构函数如何突然使Impl完成? 为什么默认的析构函数不足以使类完成?为什么shared_ptr在没有析构函数的情况下完美运行?

2 个答案:

答案 0 :(得分:4)

这一切都与my_scoped_ptr<Impl>::~my_scoped_ptr的实例化有关。

当你不提供用户定义的析构函数时,只要处理了类Holder的定义,就会定义默认的析构函数 - 基本上,它等同于在类中定义析构函数:

class Holder {
  // ... 
  ~Holder() {}
};

此析构函数需要销毁_mptr成员,因此此时~my_scoped_ptr也会被实例化,而Impl仍然不完整。

当您在标头中显式声明析构函数并在.cpp文件中定义时,~my_scoped_ptr的实例化发生在该定义的位置 - 到那时,Impl已完成。< / p>

std::shared_ptr通过在运行时,在其构造函数中,在第一次传递原始指针的位置捕获删除器,并将其存储在控制块中来解决此问题。您甚至可以将std::shared_ptr<Derived>分配给std::shared_ptr<Base>,后者最终会调用正确的析构函数,即使非虚拟析构函数也是如此。 std::shared_ptr可以解决这个问题,因为无论如何它需要分配额外的存储空间(对于引用计数等),所以它已经有点重量级了。另一方面,std::unique_ptr出现与my_scoped_ptr相同的问题,原因相同。

答案 1 :(得分:0)

头文件中没有完成。

~Holder();宣布了一个外部函数。

声明~Holder() = default;等同于声明~Holder() {},也就是说它提供了声明的析构函数的定义。它不能这样做,因为内部Impl类仅在此时被声明,未定义。