【问题标题】:What is the effect of call to a trivial destructor?调用微不足道的析构函数有什么影响?
【发布时间】:2020-07-18 21:35:58
【问题描述】:

调用普通析构函数会结束对象的生命周期吗? 我阅读了thisthis,但没有找到很好的解释。这些线程声明一个微不足道的析构函数调用没有效果,像struct A { int x; } a; a.~A(); a.~A(); 这样的代码是合法的。 但我在标准中找到了这个例子:

struct C { };
void f() {
    C * pc = new C;
    using C2 = C;
    pc->C::~C2(); // OK, destroys *pc
    C().C::~C(); // undefined behavior: temporary of type C destroyed twice
    using T = int;
    0 .T::~T(); // OK, no effect
    0.T::~T(); // error: 0.T is a user-defined-floating-point-literal (5.13.8)
}

这里 C 有一个简单的析构函数,但 C 类型的对象的双重破坏仍然有未定义的行为?

【问题讨论】:

  • 除非你使用了placement new,否则你不应该调用析构函数。
  • 你问的很好。未定义行为的有效影响之一是什么都没有发生,因此您必须保持警惕。 Does this link clear anything up?
  • 0.T 的“解析问题”即使您不提供 operator ""T
  • 重读问题再重读链接,没有链接也没用。
  • @user4581301 仍然没有回答我的问题。 However, if a program ends the lifetime of an non-trivial object explicitly, it must ensure that a new object of the same type is constructed in-place (e.g. via placement new) before the destructor may be called implicitly... 但是如果对象是微不足道的呢?你说它是未定义的,但我在 cppreference 上没有找到任何东西。

标签: c++ language-lawyer destructor lifetime


【解决方案1】:

从 C++20 开始,微不足道的析构函数调用结束对象的生命周期。在此之前他们没有,多次调用析构函数是有效的。

在 C++17(草案 N4659)中,琐碎的析构函数被明确排除在 [basic.life]/1.3 的生命周期结束之外,而带有琐碎析构函数的对象将继续存在,直到它们的存储持续时间结束或它们的存储被重用 ([basic.life]/1.4)。

这已更改为this draft commit 中的CWG issue 2256 分辨率。

另请注意,伪析构函数调用也会在 C++20 中结束生命周期,但在此之前没有。您在问题中链接的两个问题都在谈论此类伪析构函数调用。请参阅草案 (N4861) 的 [diff.cpp17.basic]/1 中针对 C++17 的兼容性说明。

【讨论】:

  • @Lassie 修复了它。
猜你喜欢
  • 2013-09-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多