[英]C++ Union, Struct, Member type
如果我有一個 class:
class Odp
{
int i;
int b;
union
{
long f;
struct
{
WCHAR* pwszFoo;
HRESULT hr;
};
};
}
Union 意味着,在列出的所有值中,它一次只能采用其中一個值? 這在訪問這些變量方面是如何工作的? 我如何直接訪問hr
? 如果我設置hr
,如果我嘗試訪問f
會發生什么?
這是一個非常充滿C ++標准的領域 - 基本上是一個聯合實例,按照標准只能在任何時候處理,好像它包含一個“活動”成員 - 最后一個寫入它。 所以:
union U {
int a;
char c;
};
然后:
U u;
u.a = 1;
int n = u.a;
u.c = 2;
char c = u.c;
沒關系,但是:
U u;
u.a = 1;
char c = u.c;
不是。 但是,有大量現有代碼表明兩者都可以。 並且在任何情況下都不會拋出“無效”訪問的異常。 C ++語言特別使用異常(!)。
基本上,如果您發現自己在C ++代碼中使用聯合來處理除C庫之外的任何東西,那么就會出現問題。
每次設置(寫入)聯合的成員時,基本上都會使其“活動”。 您只能閱讀當前活動的聯盟成員。 這意味着您有責任以某種方式記住哪個成員在每個時刻都處於活動狀態。
嘗試訪問聯合的非活動成員會導致未定義的行為。
請記住,您的代碼不是有效的C ++。 在C ++中沒有“匿名結構”這樣的東西。 您的結構成員必須具有名稱。 如果您的編譯器接受它,它只是您的特定編譯器支持的非標准擴展。
對,使用union
,在任何給定時間,相同的內存位置將用於表示單個成員。 因此,如果你有一個union的實例並設置hr
的值,那么如果你嘗試讀取f
的值,你就會變得垃圾。
嘗試使用以下方法訪問hr
:
union a;
a.hr = NULL;
它只是意味着您可以訪問與long或struct相同的內存。
要訪問hr
:
Odp o1;
o1.hr;
嘗試訪問“f”會給你一些結果。 它很可能代表union的其他成員作為“f”的數據類型,即在這種情況下,您可能會讀取表示為“long”數據類型的“pwszFoo”的部分或全部內容。 一般概念很簡單 - 聯盟成員在內存中共享相同的位置。
聯盟會為聯盟中最大的類型(事物)分配足夠的 memory。 因此,您可能擁有許多類型的對象,這些對象具有較大的 memory 足印,並且您一次只能將其中一個傳遞到代碼中的其他位置。 聯盟讓你這樣做。 它比傳遞 void 指針更上一層樓。 無論哪種情況,您都需要 devise 一種方法來了解聯合實例中存儲的內容。 下面的代碼是通過將 Union 包裝在一個結構中來實現這一點的簡單方法。 該結構定義了一個枚舉來標識 Union 使用的項目,並提供了一個存儲枚舉類型的地方。
union UnionItem {
int a;
float b;
double c;
};
struct UnionObj {
enum Type{
I, F, D
};
Type t;
UnionItem item;
};
UnionObj o;
o.item.b = 2.3f;
o.t = UnionObj::F;
// Usually the UnionObj would be passed to other functions or methods.
switch (o.t) {
case UnionObj::I:
cout << o.item.a;
break;
case UnionObj::F:
cout << o.item.b;
break;
case UnionObj::D:
cout << o.item.c;
break;
default:
cout << "Something wrong!";
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.