【问题标题】:Why can't a destructor have reference qualifiers?为什么析构函数不能有引用限定符?
【发布时间】:2020-02-28 08:28:49
【问题描述】:

是否有理由(除了因为标准这么规定)为什么不允许使用以下代码?

struct Foo
{
    ~Foo() && {}
    ~Foo() & {}
};

我知道这是非法的,但我想知道为什么。

我在考虑旧的避免未命名实例问题,即在使用保护对象时,例如:

void do_something()
{
    std::lock_guard{my_mutex};
    // some synchronized operation
}

这是合法代码,但显然容易出错,因为锁守卫在构造后会立即被销毁,因为它是一个临时(未命名)对象。

我本来打算做这样的事情

struct Foo
{
    ~Foo() && = delete;
    ~Foo() & = default;
};

如果类型被构造为临时类型,则会出现编译器错误。

【问题讨论】:

  • 引用限定符的目的应该是什么?
  • 你有什么样的要求?
  • 我会说,因为析构函数会破坏对象。没有理由为什么它应该有任何限定符。引用的对象永远不会被破坏。对于使用这些限定符的类,你会怎么做?
  • @Dr.-Ing.GerhardStein 不确定您所说的“引用的对象永远不会被破坏” 是什么意思。这就是悬空引用的来源。
  • 如果没有构造函数,我真的看不出有这个的意义。

标签: c++ destructor ref-qualifier


【解决方案1】:

首先,每个类必须只有一个析构函数。在析构函数上允许 ref-qualifiers 可以使析构函数重载。

另一个可能的原因是要和const and volatile qualifiers保持一致:

不得将析构函数声明为constvolatileconst volatile (9.3.2)。 constvolatile 语义 (7.1.5.1) 不适用于正在销毁的对象

我想,为了保持一致性,rvalueslvalues 之间的区别不适用于正在销毁的对象。

【讨论】:

  • 有趣,改变这种行为(如果我们允许引用限定符)会影响现有代码吗?
  • 这只是一个“因为标准这么说”的答案,并没有真正回答为什么。当然,如果我们有 &&& 析构函数,这意味着重载析构函数。这是关于的问题。
  • @Timo 我认为它会向后兼容,因为现有代码不使用它。
猜你喜欢
  • 2011-11-05
  • 2010-12-20
  • 2013-11-17
  • 2016-02-25
  • 2015-02-28
  • 2015-08-21
  • 2017-12-17
  • 2017-12-21
相关资源
最近更新 更多