3

我正在阅读 c++11 的 wiki 条目,我发现了一个不受限制的联合部分,您在其中为非平凡的成员链接调用放置新,但这里的示例与删除不匹配。

所以我的问题是:您是否需要无限制联合的展示位置删除?如果是,如何?如果不是,为什么?调用析构函数就足够了吗?

例子:

class U_t
{
  public:
    union U
    {
        string s;
        U () { new (s) string(); }
    }
    U _data;
    ~U_t () { 
       _data.s.~string();
       //and now what?
    }
}
4

1 回答 1

2

§ 9.5/2 如果联合的任何非静态数据成员具有非平凡的默认构造函数、复制构造函数、移动构造函数、复制赋值运算符、移动赋值运算符或析构函数,则联合的相应成员函数必须是用户-提供,否则它将为联合隐式删除。

§ 9.5/3 由于 std::string 声明了所有特殊成员函数的重要版本,[联合] 将具有隐式删除的默认构造函数、复制/移动构造函数、复制/移动赋值运算符和析构函数。要使用 [联合],这些成员函数中的部分或全部必须由用户提供。

§ 9.5/4 通常,必须使用显式析构函数调用和放置新运算符来更改联合的活动成员。

所以是的,它需要一个析构函数调用,类似于你所拥有的。

但是,要安全地使用这样的东西会复杂得多,因为您必须不断跟踪活动的类型。安全地使用非 POD 类型的联合是非常困难的。如果我是你,只使用 POD,或者使用boost::variant

于 2012-09-11T00:02:32.953 回答