Jon*_*Mee 21 c++ destructor unions standard-layout c++11
C++ 11允许在以下标准中使用标准布局类型union
:Union的成员具有用户定义的构造函数
我的问题是:我是否保证在union
超出范围时会调用自定义析构函数?
我的理解是我们必须在切换时手动销毁和构建:http://en.cppreference.com/w/cpp/language/union#Explanation
但是像这样的例子怎么样:
{
union S { string str;
vector<int> vec;
~S() {} } s = { "Hello, world"s };
}
Run Code Online (Sandbox Code Playgroud)
当s
超出范围时,我是否将内存泄漏到堆上分配的字符串,因为我没有调用string
析构函数?
Nat*_*ica 17
在您的示例中,您提供的str
不会被破坏.[class.union]/2中的标准状态
联合可以具有成员函数(包括构造函数和析构函数),但不具有虚函数(10.3).工会不得有基类.联合不得用作基类.如果联合包含引用类型的非静态数据成员,则程序格式错误.联合的至多一个非静态数据成员可以具有支撑或等于初始化器.[ 注意:如果union的任何非静态数据成员具有非平凡的默认构造函数(12.1),复制构造函数(12.8),移动构造函数(12.8),复制赋值运算符(12.8),移动赋值运算符(12.8),或者析构函数(12.4),联合的相应成员函数必须是用户提供的,否则将为联合隐式删除(8.4.3).- 结束说明 ]
强调我的
所以,因为两者str
并vec
具有不平凡的,你需要为自己的工会为他们提供特殊的成员函数.
请注意,根据bogdan的评论,空的析构函数是不够的.在[class.union]/8中我们有
[...]如果X是联盟,其变体成员是非静态数据成员; [...]
因此,这个联盟的所有成员都是变体.然后,如果我们看一下[class.dtor]/8
在执行析构函数体并破坏正文中分配的任何自动对象之后,类X的析构函数调用X的直接非变量非静态数据成员的析构函数[...]
因此析构函数不会自动销毁union的成员,因为它们是变体.
Run Code Online (Sandbox Code Playgroud)struct TU { int type; union { int i; float f; std::string s; } u; TU(const TU& tu) : type(tu.type) { switch (tu.type) { case TU_STRING: new(&u.s)(tu.u.s); break; case TU_INT: u.i = tu.u.i; break; case TU_FLOAT: u.f = tu.u.f; break; } } ~TU() { if (tu.type == TU_STRING) u.s.~string(); } ... };
这确保了正确的成员被破坏或只是使用std::variant
或boost::variant
归档时间: |
|
查看次数: |
5661 次 |
最近记录: |