union Test {int i_;std::string s_;};
int main(){Test t;t.s = "abc";t.i = 100;return 0;}C++98中,上述代码无法编译通过。枚举中的std::string不是POD。用反证法解释一下。
假设t.s="abc"编译成功,则t.i=100会直接破坏string中的指针数据。
C++11中,上述代码也无法编译通过。但是原因是说,Test的默认构造,析构等函数都被打上了delete标志。
相当于 Test::Test() = delete ; ~Test::Test() = delete ;直觉上,让int和string共享相同的存储空间好像能实现,只要小心处理一下即可。
我们只要重新定义Test的构造函数,析构函数,赋值函数等等......
这就是非受限联合体的由来,你可以混用std::string和int,只要不要胡来即可。
#include <iostream>#include <string>using namespace std;union Test {enum class Tag { number, text } type; // discriminantint i_;std::string s_;Test& operator=(const Test& w);Test(int);Test(std::string);~Test();};Test::Test(int i){type = Tag::number;i_ = i;}Test::Test(std::string s){type = Tag::text;new(&s_) std::string(s);}Test& Test::operator=(const Test& w){if (type==Tag::text && w.type==Tag::text) {s_ = w.s_; // usual string assignmentreturn *this;}
if (type==Tag::text) s_.~string(); // destroy (explicitly!)switch (w.type) {case Tag::number:i_ = w.i_;break;case Tag::text:new(&s_) std::string(w.s_);break; // placement new}
type = w.type;return *this;}Test::~Test(){if (type==Tag::text){s_.~string();}
}int main(){Test t1(100);cout << t1.i_ << endl;Test t2("abc");cout << t2.s_ << endl;t2 = t1;cout << t2.i_ << endl;return 0;}
学习笔记:非受限联合体
最新推荐文章于 2024-03-25 13:12:26 发布