2011-04-05 40 views

回答

21

有對維基百科的解釋:http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions

搜索有第一問的C++ 0x之前擁有解釋相關。

無限制工會

在標準C++ 有什麼類型的對象 可以成爲工會成員的限制。 例如,聯合不能包含任何定義構造函數的非重要對象 。 C++ 0x將減輕這些限制的一些 ,允許聯盟 用於更多類型,它們以前不允許使用 。[6]這是 聯合的一個簡單的例子中允許的C++ 0x:

//for placement new 
#include <new> 

struct Point { 
    Point() {} 
    Point(int x, int y): x_(x), y_(y) {} 
    int x_, y_; 
}; 
union U { 
    int z; 
    double w; 
    Point p; // Illegal in C++; point has a non-trivial constructor. 
       // However, this is legal in C++0x. 
    U() { new(&p) Point(); } // No nontrivial member functions are 
           //implicitly defined for a union; 
           // if required they are instead deleted 
           // to force a manual definition. 
}; 

的變化不會打破任何 現有代碼,因爲它們只放鬆 當前規則。

8

沒有什麼比我們一直擁有的舊的工會,一次包含一個成員,具有不同類型的對象。

這個改變就是你現在被允許在一個聯合中存儲非POD類型。但是,您將負責明確構建和銷燬該成員。

從N3242:

[實施例:考慮具有u非靜態數據成員 類型M的m×n個類型N的和U的聯合類型的對象。如果M具有一個非平凡的析構函數並且N有一個非平凡的構造函數 (例如,如果他們聲明或繼承了虛函數),則u的活動成員可以使用析構函數和放置new運算符如下安全地從m切換到n:
um〜 M();
new(& u.n)N;
-end example]

不是一個廣泛使用的功能,IMO。

1

它擴大工會允許任何類型的,不只是「普通的舊數據」,給你更多的靈活性,以存儲不同類型在同一位置的數據,而不訴諸人工指針兩輪牛車。

你爲此付出的代價是你必須做一些謹慎的記錄。用一個普通的舊數據聯合賦值就足以改變「當前類型」並且讀取錯誤的類型可能會導致帶有標籤的數據,但不會比這更多。如果使用非普通的舊數據聯合體,則必須跟蹤當前類型,並手動調用corect構造函數和析構函數以更改當前類型並在整體銷燬聯合時正確清理它們。如果您嘗試讀取或寫入擰緊類型,可能會發生不良事情