Base
union U{
char a;
int b;
};
U u;
sizeof( u ) == 4 == int;
u.a = '#';
// 此时不要使用u.b
u.b = 123'
// 此时不要使用u.a
联合体: 将一些不同类型Type的变量,放到“同一个内存区域”使用
即'内存覆盖技术',
匿名写法
正常写法:
union u{
...
};
class ST{
u u1;
}
但如果说,u这个结构体 他不会在其他地方用到,只有ST类里面用这一次而已
即,无需将他单独设置成全局的(就和匿名函数的用处一样)
可以写成:
class ST{
union{
...
}u1;
};
这个union没有类型名,他只有一个变量名。 用法和上面一样
示例
class grade{
public:
int type;
union{
int data;
string comment;
}score;
};
有一个成绩属性,要么是数值(83分),要么是字符串评语(“good”)
grade g1, g2;
g1.type = 1, g1.score.data = 83;
g2.type = 2, g1.score.comment = "good";
在实际用的时候,看type类型,如果是1 则使用score.data,如果是2 则使用score.comment
禁止显式构造函数
官方:
C++ forbids unions from including types that have
non-default constructors or destructors
正确示例:
class ST{
}
union U{
ST t;
}
错误示例:
class ST{
ST(){}
}
union U{
ST t;
}
错误示例:
union U{
string s; ' string里,也有自定义的构造等 '
};
' 当创建对象U u时,就会报错 '
c++规定: 联合体union里的类型,不可以有 '带有自定义的 构造/析构/拷贝构造 的类'
如果c++标准允许联合体中有自定义的构造函数,那在进行联合体空间分配时要不要执行这个构造函数?
(1) 假设要,而联合体中有多个自定义了构造函数的类存在,每个构造函数的实现体是对该联合体的占据的空间执行相关初始化操作,那么联合体占据的空间和程序员设计的初衷不一样了:程序员使用到联合体中的某个类对象时,它是一个没有等价于没有被初始化,或者瞎初始化的对象。另外,如果其中一个类的自定义构造函数做了动态内存分配,而该类不是程序员访问联合体的访问方式,那么该动态分配的内存空间将会造成内存泄漏。
(2) 假设不要,而联合体中的类包含了虚函数,那么该类的虚函数表将不会得到初始化,虚函数无意义。
综上,c++标准决定,c++联合体中不允许定义有自定义构造函数的类,同理,不允许定义自定义了拷贝构造函数、析构函数的类。那为什么用默认的构造/析构/拷贝构造函数就可以?因为c++标准知道默认的构造/析构函数的操作的实现体什么都不做,拷贝构造函数只是实现浅拷贝。