C++ Primer 5th笔记(chap 19 特殊工具与技术)union
1. 定義
聯合( union) 是一種特殊的類。 一個 union 可以有多個數據成員, 但是在任意時刻的某個成員賦值之后, 該 union 的其他成員就變成未定義的狀態了。
- 對象的存儲空間至少要能容納它的最大的只有一個數據成員可以有值。
- union 既不能繼承自其他類, 也不能作為基類使用
- 可用來表示一組類型不同的互斥值
1.1 匿名 union( anonymous union)
一個未命名的 union, 并且在右花括號和分號之間沒有任何聲明
union {char cval;int ival;double dval; }; // 未命名對象, 我們可以直接訪問它的成員 cval = 'a'; // 為匿名union賦一個新值 ival = 42; // 該對象當前保存的值是42- 在匿名 union 的定義所在的作用域內該 union 的成員都是可以直接訪問的
- 不能包含受保護的成員或私有成員, 也不能定義成員函數
1.2 內置類型
當 union包含的是內置類型的成員時, 編譯器將按照成員的次序依次合成默認構造函數或拷貝控制成員。 但是如果union 含有類類型的成員,并且該類型自定義了默認構函數或拷貝控制成員, 則編譯器將為union合成對應的版本并將其聲明為刪除的。
eg. string 類定義了五個拷貝控制成員以及一個默認構造函數。 如果有 string 類型的成員, 并且沒有自定義默認構造函數或某個拷貝控制成員, 則編譯器將合成缺少的成員并將其聲明成刪除的。 如果在某個類中含有一個含有刪除的拷貝控制成員, 則該類與之對應的拷貝控制操作也將是刪除的。
1.3 使用類管理 union 成員
通常會定義一個獨立的對象, 該對象稱為稱為union的判別式 (discriminant)
eg. 使用 tok 作為判別式。 當 union 存儲的是一個 int 值時, tok 的值是 INT: 當union 存儲的是一個 string 值時, tok 的值是 STR: 以此類推
class Token { public://因為union含有一個string成員,所以Token必須定義拷貝控制成員//定義移動構造函數和移動賦值運算符的任務Token() :tok(INT), ival{ 0 }{ }Token(const Token& t) :tok(t.tok) { copyUnion(t); }Token& operator=(const Token&);//如果union含有一個string成員,則我們必須銷毀它~Token() { if (tok == STR) sval.~string(); }Token& operator=(const string&);Token& operator=(int);Token& operator=(double);Token& operator=(char);private:enum {INT,CHAR,DBL,STR} tok; //判別式union {//匿名unionchar cval;int ival;double dval;string sval;};//每個Token對象含有一個該未命名union類型的未命名成員//檢查判別式,然后酌情拷貝union成員void copyUnion(const Token&); };Token& Token::operator=(const string& s) {if (tok == STR)sval = s;elsenew(&sval) string(s);tok = STR;return *this; }Token& Token::operator=(int i) {if (tok == STR) sval.~string();tok = INT;ival = i;return *this; }Token& Token::operator=(double d) {if (tok == STR) sval.~string();tok = DBL;dval = d;return *this; }Token& Token::operator=(char c) {if (tok == STR) sval.~string();tok = CHAR;cval = c;return *this; }//管理需要拷貝控制的聯合成員 void Token::copyUnion(const Token& t) {switch (t.tok) {case INT:ival = t.ival; break;case STR:new(&sval) string(t.sval); break;case CHAR:cval = t.cval; break;case DBL:dval = t.dval; break;} }Token& Token::operator=(const Token& t) {//如果此對象的值是string而t的值不是,而我們必須釋放原來的stringif (tok == STR && t.tok != STR) sval.~string();if (tok == STR && t.tok == STR)sval = t.sval;elsecopyUnion(t);tok = t.tok;return *this; }總結
以上是生活随笔為你收集整理的C++ Primer 5th笔记(chap 19 特殊工具与技术)union的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EOS 智能合约源代码解读 (14)sy
- 下一篇: C++ Primer 5th笔记(cha