c++ - 放置新的 STL 容器并在之后安全地销毁它

标签 c++ c++11 destructor unions placement-new

这段代码实现了一个不受限制的 union ,它提供了通过名称和索引对其三个成员中的任何一个进行访问。

由于 std::string 是非平凡构造和销毁的,我需要为 union 提供特殊的构造函数和析构函数。

#include <iostream>
#include <string>

using namespace std ;

union MyUnion{
    string parts[3] ;
    struct{ string part1, part2, part3 ; } ;
    
    MyUnion(){
        new(parts+0) string ; //constructs the 3 strings in-place
        new(parts+1) string ;
        new(parts+2) string ;
    }
    ~MyUnion(){
        parts[0].~string() ; //calls string's destructor
        parts[1].~string() ;
        parts[2].~string() ;
    }
} ;

int main(){
    
    MyUnion u ;
    
    u.part1 = "one" ; //access by name
    u.part2 = "two" ;
    u.part3 = "three" ;

    cout << u.parts[0] << endl ; //access by index
    cout << u.parts[1] << endl ;
    cout << u.parts[2] << endl ;
}

这个例子编译并运行良好(表面上),但我的问题是:

  • 这样做安全吗?
  • 我能确定不会有内存泄漏吗?
  • 如果 string 的构造函数抛出异常怎么办?是否需要捕获它以免试图破坏从未构建的对象?

注意事项

代码在 VC2015 中编译,它确实支持未命名的结构。请忽略该细节。

最佳答案

Is it safe to do this?

没有。首先,通用初始序列规则只允许成员读取,而不允许写入:

In a standard-layout union with an active member (9.3) of struct type T1, it is permitted to read a non-static data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2; the behavior is as if the corresponding member of T1 were nominated.

其次,通用初始序列是标准布局类型的一个特征:

The common initial sequence of two standard-layout struct (Clause 9) types is [...]

std::string 不需要是标准布局。

关于c++ - 放置新的 STL 容器并在之后安全地销毁它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43669004/

相关文章:

c++ - 不同指针类型之间的无效比较 : 'type*' and 'type&(*)()'

c++ - 使用精神以替代方式解析结构时混淆输出

c++ - 对具有重载运算符的类型进行就地销毁->

c++ - 显式调用时析构函数被调用两次

c# - 什么时候在 WCF 服务中调用析构函数

c++ - 如何做虚拟化?

c++ - 使用 gcc c++ 获取 Windows 版本

C++ - Ubuntu 16.04 中个人类(class)的文件夹

c++ - 如何在 C++ 中使用 cin 隐藏用户输入?

c++ - 如何在参数包不是最后一个参数的 C++ 中编写可变参数模板函数?