上一篇:http://www.BkJia.com/kf/201201/116372.html
18.5 聯合:節省空間的類
聯合(union)是一種特殊的類。一個union對象可以有多個數據成員,但在任何時刻只有一個成員可以有值。當將一個值賦給union對象的一個成員的時候,其他所有成員都變為未定義的。
為union對象分配的存儲的量至少與包含其最大數據成員的一樣多。像任何類一樣,一個union定義了一個新的類型。
1.定義聯合
聯合提供了便利的辦法表示一組相互排斥的值,這些值可以是不同類型的。
一個union定義了以關鍵字union開始,後接(可選的)union名字,以及一組以花括號括住的成員聲明。
class AndersClass{};
union UnionClass{
char *cval;
int ival;
double dval;
AndersClass anders;
};
static union{
char cval;
int *ival;
double dval;
AndersClass anders;
};
2. 沒有靜態數據成員、引用成員或類數據成員
某些(但不是全部)類特征同樣適用於union。例如,像任何類一樣,union可以指定保護標記使成員成為公用的、私有的或受保護的。默認情況下,union表現得像struct:除非另外指定,否則union的成員都為public成員。
union也可以定義成員函數,包括構造函數和析構函數。但是,union不能作為基類使用,所以成員函數不能為虛數。
union不能具有靜態數據成員或引用成員,而且union不能具有定義了構造函數、析構函數或賦值操作符的類類型的成員。
3. 使用聯合類型
union的名字是一個類型名。像其他內置類型一樣,默認情況下union對象是未初始化的。可以用與顯式初始化簡單類對象一樣的方法顯式初始化union對象。但是,只能為第一個成員提供初始化式。該初始化式必須包括在一對花括號中。
UnionClass uc={new char('a')};
4. 使用聯合的成員
可以使用普通成員訪問操作符(.和->)訪問union類型對象的成員。
UnionClass uc={new char('a')};
cout<<*uc.cval<<endl;
給union對象的某個數據成員一個值使得其他數據成員變為未定義的。使用union對象時,我們必須總是知道union對象中當前存儲的是什麼類型的值。通過錯誤的數據成員檢索保存在union對象中的值,可能會導致程序崩潰或者其他不正確的程序行為。
避免通過錯誤成員訪問union值的最佳方法是,定義一個單獨的對象跟蹤union中存儲了什麼值。這個附加對象稱為union的判別式(discriminant)。
5. 嵌套聯合
union最經常用作嵌套類型,其中判別式是外圍類的一個成員。
class TheClass{
public:
enum ClassKind{INT,CHAR,DBL};
ClassKind ck;
union {
char cval;
int ival;
double dval;
} val;
};
TheClass tc=TheClass();
tc.val.cval=='1';
6. 匿名聯合
不用於定義對象的未命名union稱為匿名聯合(anonymous union)。匿名union的成員的名字出現在外圍作用域中。
class TheClass2
{
public:
union {
char cval;
int ival;
double dval;
};
};
TheClass2 tc2=TheClass2();
tc2.cval='1';
匿名union不能有私有成員或受保護成員,也不能定義成員函數。
摘自 xufei96的專欄