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;}
学习笔记:非受限联合体
最新推荐文章于 2025-06-29 21:06:15 发布
本文探讨了C++中非受限联合体的概念及其实现方式,通过定义成员变量和自定义构造、析构函数,实现了int与std::string类型的安全共存。同时,通过实例演示了如何在不同类型的成员间进行安全转换。
847

被折叠的 条评论
为什么被折叠?



