【问题标题】:Is destructor of empty unique_ptr w/o custom deleter trivial没有自定义删除器的空 unique_ptr 的析构函数是微不足道的
【发布时间】:2015-12-20 12:26:57
【问题描述】:

给定一个代码(真正的伪代码):

struct A { /* ... */ }; // assume is non-trivial
struct B { /* ... */ }; // assume is non-trivial

using UA = std::unique_ptr< A >;
using UB = std::unique_ptr< B >;

union U
{

    UA a;
    UB b;

};

U u{std::make_unique< A >(/* init */)};
u.a = nullptr; // destructor of underlying type A called
// u.a.~UA(); // destructor of smart pointer itself
::new (&U.b) UB{std::make_unique< B >(/* init */)};

是否可以省略U::a 成员的析构函数调用?这个问题的灵感来自于关注quote 关于std::unique_ptr::~unique_ptr

如果 get() == nullptr 没有效果。

我可以认为这种情况下的 d-tor 是微不足道的(如下所述)吗?

我认为std::unique_ptr&lt; T &gt; 的内部(在std::unique_ptr 没有自定义删除器的情况下是唯一的)数据成员(比如p)是T * 类型。在分配p = nullptr; 之后,似乎可以对这样的std::unique_ptr 不做任何事情,以便将其存储用于其他目的。是正确的结论吗?

【问题讨论】:

  • @deviantfan 这只是一个优化。在代码的现实生活部分(堆变体类)中,我应该交换两个类似U 的结构。该代码中没有放置::new,因此不应显式调用析构函数(只是成语)。

标签: c++ destructor c++14 smart-pointers unique-ptr


【解决方案1】:

我可以认为这种情况下的 d-tor 是微不足道的吗?

没有。普通析构函数是 C++ 中正式定义的术语,非空析构函数绝不是微不足道的。琐碎性是一种类型的编译时属性,因此必须执行运行时测试并有条件地调用删除器的析构函数不可能是琐碎的。

但是,如果程序的正确性不依赖于析构函数的效果,那么省略销毁对象总是有效的。

[basic.life] p4:

对于具有非平凡析构函数的类类型的对象,在重用或释放对象占用的存储空间之前,程序不需要显式调用析构函数;但是,如果没有显式调用析构函数,或者没有使用 delete-expression (5.3.5) 来释放存储,则不应隐式调用析构函数,并且任何依赖于析构函数产生的副作用具有未定义的行为。

由于unique_ptr为空时没有副作用,程序不依赖它,所以省略析构函数也可以。

【讨论】:

  • s/doesnot not/does not/ 双重否定本身就是初始陈述。
猜你喜欢
  • 2015-08-15
  • 2014-02-02
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 2020-02-25
  • 1970-01-01
相关资源
最近更新 更多