2010年11月3日 星期三

[C++ 小學堂] C++ Gossip : 物件基礎 - 封裝的進階議題 (Union)


轉載自 這裡
前言 :
熟悉C的程序員應該都知道 union 的用法,利用union可以用相同的存儲空間存儲不同型別的數據類型,從而節省內存空間。 當訪問其內成員時可用"."和"->"來直接訪問。 在C++出現後,它繼承了union並保留了其在C中的特性。

Union 結構體介紹 :
union是一種特殊的類別,使用關鍵字union來定義,union維護足夠的空間來置放多個資料成員中的「一種」,而不是為每一個資料成員配置空間, 在union中所有的資料成員共用一個空間,同時間只能儲存其中一個成員的資料,一個定義union的例子如下 :
  1. union StateMachine {  
  2.     char character;  
  3.     int number;  
  4.     char *str;  
  5.     double exp;  
  6. };  
一個union只配置一個足夠大的空間以來容納最大長度的資料成員,以上例而言,最大長度是double型態,所以StateMachine的記憶體空間 就是double型態的長度,union的成員預設為public,也可以宣告為protected或private,當中可以定義建構函式、解構函式與 成員函式,例如 :
- 範例代碼 :
  1. #include   
  2.   
  3. union StateMachine1 {  
  4. public:  
  5.     char character;  
  6.     int number;  
  7.     char *pStr;  
  8.     StateMachine1(char c) {  
  9.         character = c;  
  10.     }  
  11.     StateMachine1(int n) {  
  12.         number = n;  
  13.     }  
  14.     StateMachine1(char* s) {  
  15.         pStr = s;  
  16.     }  
  17. };  
  18.   
  19. using namespace std;  
  20. void main() {  
  21.     StateMachine1 machine(1);  
  22.     cout << machine.number << endl;   
  23. }  

由於union的資料成員共用一個記憶體空間,所以必須存取正確的資料成員才能正確的取出資料,可以使用一個額外的變數或列舉型態來記錄最後一次使用空間 的是哪個資料成員,例如 :
- 範例代碼 :
  1. #include   
  2.   
  3. union StateMachine1 {  
  4. public:  
  5.     char character;  
  6.     int number;  
  7.     char *pStr;  
  8.     StateMachine1(char c) {  
  9.         character = c;  
  10.     }  
  11.     StateMachine1(int n) {  
  12.         number = n;  
  13.     }  
  14.     StateMachine1(char* s) {  
  15.         pStr = s;  
  16.     }  
  17. };  
  18.   
  19. enum State {character, number, str};  
  20. void main() {  
  21.     State state = character;  
  22.     StateMachine1 machine('J');  
  23.     if(state == character) {  
  24.         cout << "Character=" << machine.character << endl;  
  25.     } else if(state == number) {  
  26.         cout <<  "Number=" << machine.number << endl;  
  27.     } else if(state == str) {  
  28.         cout << "String=" << machine.pStr << endl;  
  29.     } else {  
  30.         cout << "Illegal State!" << endl;  
  31.     }  
  32. }  

另外要注意的是,union的成員不可以為靜態、參考,如果是自訂型態的話,該自訂型態成員不可以有建構函式、解構函式或是複製指定運算子.

補充說明 :
C++中union的應用剖析
union中不可以存儲TestUnion類的對象,但在C中union可以存儲struct呀,為什麼不能存儲類的對象呢? 很簡單,請問,在C中union可以存儲帶有構造函數的struct嗎? 對了,在C中的struct是沒有構造函數的。 所以如果C++中union可以存儲有構造函數的類的對象就不太符合邏輯,那不是說C++和C完全兼容嗎? 不錯,正因為這一點,C++中union不可以存儲有構造函數的類的對象,但是可以存儲不帶構造函數的類的對象,這樣就和C保持一致了

[C++ 小學堂] 結構, 共用體與鏈表 : 共用體
This message was edited 6 times. Last update was at 04/08/2010 17:02:52

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...