C++聯合
目錄 |
1 聯合簡介
聯合是一個結構,但結構的數據成員各自佔用一塊內存空間, 它們形成一個整體, 所佔空間是全部成員所佔空間的總和。聯合與此不同, 它的數據成員重疊擠占同一段內存空間, 有點像"一套班子, 多塊招牌", 它們形成的整體, 所佔空間取成員中佔用空間最大者。
2 定義與聲明
下面定義了一個名為test的聯合類型,它含有兩個成員,一個為整型,成員名為office;另一個為字符數組,數組名為teacher。聯合定義之後,即可進行聯合變量聲明,被聲明為test類型的變量,可以存放整型量office或存放字符數組teacher。
union test { test() { } int office; char teacher[5]; };
聲明分為三種方式:
- 第一種,先定義再聲明:
union test { test() { } int office; char teacher[5]; }; union test a,b; //说明a,b为test类型
- 第二種,定義時同時聲明:
union test { test() { } int office; char teacher[5]; } a,b;
- 第三種,直接聲明,之後再也不能再添加其他的變量:
union { test() { } int office; char teacher[5]; } a,b;
3 聯合的使用
對聯合變量的賦值,使用都只能是對變量的成員進行。
聯合變量的成員表示為:聯合變量名.成員名
例如,a被說明為test類型的變量之後,可使用a.class、a.office
不允許只用聯合變量名作賦值或其它操作,也不允許對聯合變量作初始化賦值,賦值只能在程序中進行。
還要再強調說明的是,一個聯合變量,每次只能賦予一個成員值。換句話說,一個聯合變量的值就是聯合變員的某一個成員值。
4 匿名聯合
匿名聯合僅僅通知編譯器它的成員變量共同享一個地址,而變量本身是直接引用的,不使用通常的點號運算符語法。例如:
#include <iostream> void main() { union{ int test; char c; }; test=5; c='a'; std::cout<<i<<" "<<c; }
正如所見到的,聯合成分象聲明的普通局部變量那樣被引用,事實上對於程序而言,這也正是使用這些變量的方式。另外,儘管被定義在一個聯合聲明中,他們與同一個程序快那的任何其他局部變量具有相同的作用域級別。這意味這匿名聯合內的成員的名稱不能與同一個作用域內的其他一直標誌符衝突。
對匿名聯合還存在如下限制:
- 因為匿名聯合不使用點運算符,所以包含在匿名聯合內的元素必須是數據,不允許有成員函數,也不能包含私有或受保護的成員。
- 全局匿名聯合必須是靜態(static)的,否則就必須放在匿名名字空間中。
- 聯合裡面的東西共享內存,所以靜態、引用都不能用,因為他們不可能共享內存。
- 不允許存放帶有構造函數、析夠函數、複製拷貝操作符等的類,因為他們共享內存,編譯器無法保證這些對象不被破壞,也無法保證離開時調用析夠函數。
5 如何有效的防止訪問出錯
使用聯合可以節省內存空間,但是也有一定的風險:聯合內的數據共享內存,而且同時只能有一個變量出現,因此就有可能出現交錯訪問的現象,即通過一個不適當的數據成員獲取當前對象的值,比如
union Fudge{ int i; int *p; }; int* cheat(int i) { Fudge a; a.i = i; return a.p; //bad usee }
上例在使用的時候,內存中儲存的是 i,但訪問的卻是 p,因此就會出現錯誤。為了防止這樣的錯誤,我們必須定義一個額外的對象,來跟蹤當前被存儲在聯合中的值得類型,我們稱這個額外的對象為:union的判別式。
另一個比較好的經驗是,在處理作為類成員的union對象時,為所有union數據類型提供一組訪問函數。
6 參見
- C/C++中的聯合 union. ︶ㄣ第二名. 2009-11-11.