<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # (廣義的)聯合體 在C++98(或更早)版本中,union的成員類型,必須不含自定義構造/析構函數或者賦值操作符。 ``` union U { int m1; complex m2; //錯誤(明顯的):complex擁有構造函數 //錯誤(不那么明顯):string的內部數據只能嚴格地由其構造函數, // 拷貝構造函數,和析構函數去維護 string m3; }; ``` 亦即: ``` U u; // 使用哪個成員的構造函數呢? u.m1 = 1; // 給整型成員賦值 string s = u.m3; //災難:從string成員拷貝 ``` 顯而易見,把值寫入一個成員,之后又讀取另外一個成員的做法是給自己找麻煩,然而人們往往并非刻意而為(多因失誤導致) 。 C++11對union的限制條件進行了放寬,以允許更靈活廣泛的成員類型。其中值得特別指出的是,帶有自定義構造函數/析構函數的類型現在也可作為union的成員了。此外,為使“靈活”不至成為脫韁野馬,新標準又特別引入了“第四條軍規”(譯注:參見下文),并倡導使用“可識別union”(譯注:參見下文Widget樣例以及Boost::Any和Boost::Variant)。 C++11中的對union的限制條件重新定義如下: * 不含虛函數(與C++98相同) * 不含引用成員(與C++98相同) * 沒有基類(與C++98相同) * 若union的某個成員的類型含有自定義構造/拷貝/析構函數,那么該union的相應構造/拷貝/析構函數將會被自動“禁用”(譯注:在C++11中我們可以使用delete關鍵字來“禁用”構造/析構函數),隨之而來的后果是:該union不能被實例化成對象。(新增的所謂“第四條軍規”) 例如: ``` union U1 { int m1; complex m2; // ok }; union U2 { int m1; string m3; // ok }; ``` 上述代碼看起來容易出問題(譯注:例如有人實例化了U2類型的對象并給其m1成員賦值之后,當union析構時,m3的析構函數可能會crash),但是有了第四條軍規,剛才的隱含問題便迎刃而解(譯注:通過編譯錯誤)。即: ``` U1 u; // ok u.m2 = {1,2}; // ok:給complex成員賦值 U2 u2; // 編譯錯誤: string類含有析構函數,因而U2的析構函數已被自動禁用 //(譯注:析構函數被禁用意味著不允許在棧上實例化U2對象,否則無法析構) U2 u3 = u2; // 編譯錯誤:string類含有拷貝構造函數, // 因而U2類型同樣也不能被拷貝構造 ``` 這樣看來,先前定義的U2幾乎沒什么實際用途了。唯一可能用到這種奇葩union的地方是,把它嵌到結構體里并且額外記錄其“當值”成員類型——也就是所謂的“可識別union”。樣例如下: ``` class Widget { // 用union存儲的“三態”Widget private: // 用以實現“可識別union”的“當值”類型標記 enum class Tag { point, number, text } type; union { // 三態的具體存儲形式 point p; // point類含有構造函數 int i; string s; // string類含有默認的構造/拷貝/析構函數 }; // ... // 由于string中存在拷貝函數,所以需要“手工拷貝”union Widget& operator=(const Widget& w) { // 譯注:從text態到text態 if (type==Tag::text && w.type==Tag::text) { s = w.s; // 直接使用string的賦值運算符 return *this; } // 譯注:從text態到其他態,意味著union不再用于存放string // 由于union的拷貝函數已被自動禁用, // 所以需要有人手工釋放string原先所占資源 if (type==Tag::text) s.~string(); // 此處需要顯式析構 switch (w.type) { case Tag::point: p = w.p; break; // 普通的拷貝 case Tag::number: i = w.i; break; // 譯注:C++98/03標準中的的原地拷貝構造語法 case Tag::text: new(&s)(w.s); break; // placement new } type = w.type; return *this; } }; }; ``` 其他參考文獻: * [N2544=08-0054] Alan Talbot, Lois Goldthwaite, Lawrence Crowl, and Jens Maurer: [Unrestricted unions (Revison 2)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf) (翻譯:張瀟)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看