C++中使用union的幾點思考
更新時間: 2007-05-08 14:44:47來源: 粵嵌教育瀏覽量:960
這段時間整理舊資料,看到一些文章,雖然講的都是些小問題,不大可能用到,但也算是一個知識點,特整理出來與大家共享。與此相關(guān)的那篇文章的作者的有些理解是錯誤的,我寫此文,也是糾正為了作者的一些錯誤認識。當然,如果我的理解有任何錯誤,也懇請大家批評指正。
C++雖說被B.S.稱作一門新語言,但它畢竟與C有著千絲萬縷的聯(lián)系,雖然B.S.一再堅持,但我還是愿意把C++看作是C ++。
我們應(yīng)該按照C中的convention去使用union,這是我這篇文章要給出的觀點。雖然C++使得我們可以擴展一些新的東西進去,但是,我建議你不要那樣去做,看完這篇文章之后,我想你大概也是這么想的。
C由于沒有類的概念,所有類型其實都可以看作是基本類型的組合,因此在union中包含struct也就是一件很自然的事情了,到了C++之后,既然普遍認為C++中的struct與class基本等價,那么union中是否可以有類成員呢?先來看看如下的代碼:
struct TestUnion
{
TestUnion() {}
};
typedef union
{
TestUnion obj;
} UT;
int main (void)
{
return 0;
}
編譯該程序,我們將被告知:
error C2620: union ‘__unnamed‘ : member ‘obj‘ has user-defined constructor or non-trivial default constructor
而如果去掉那個什么也沒干的構(gòu)造函數(shù),則一切OK。
為什么編譯器不允許我們的union成員有構(gòu)造函數(shù)呢?我無法找到關(guān)于這個問題的比較權(quán)威的解釋,對這個問題,我的解釋是:
如果C++標準允許我們的union有構(gòu)造函數(shù),那么,在進行空間分配的時候要不要執(zhí)行這個構(gòu)造函數(shù)呢?如果答案是yes,那么如果TestUnion的構(gòu)造函數(shù)中包含了一些內(nèi)存分配操作,或者其它對整個application狀態(tài)的修改,那么,如果我今后要用到obj的話,事情可能還比較合理,但是如果我根本就不使用obj這個成員呢?由于obj的引入造成的對系統(tǒng)狀態(tài)的修改顯然是不合理的;反之,如果答案是no,那么一旦我們今后選中了obj來進行操作,則所有信息都沒有初始化(如果是普通的struct,沒什么問題,但是,如果有虛函數(shù)呢?)。更進一步,假設(shè)現(xiàn)在我們的union不是只有一個TestUnion obj,還有一個TestUnion2 obj2,二者均有構(gòu)造函數(shù),并且都在構(gòu)造函數(shù)中執(zhí)行了一些內(nèi)存分配的工作(甚至干了很多其它事情),那么,如果先構(gòu)造obj,后構(gòu)造obj2,則執(zhí)行的結(jié)果幾乎可以肯定會造成內(nèi)存的泄漏。
鑒于以上諸多麻煩(可能還有更多麻煩),在構(gòu)造union時,編譯器只負責分配空間,而不負責去執(zhí)行附加的初始化工作,為了簡化工作,只要我們提供了構(gòu)造函數(shù),就會收到上面的error。
同理,除了不能加構(gòu)造函數(shù),析構(gòu)函數(shù)/拷貝構(gòu)造函數(shù)/賦值運算符也是不可以加。
此外,如果我們的類中包含了任何virtual函數(shù),編譯時,我們將收到如下的錯誤信息:
error C2621: union ‘__unnamed‘ : member ‘obj‘ has copy constructor
所以,打消在union中包含有構(gòu)造函數(shù)/析構(gòu)函數(shù)/拷貝構(gòu)造函數(shù)/賦值運算符/虛函數(shù)的類成員變量的念頭,老老實實用你的C風格struct吧!
不過,定義普通的成員函數(shù)是OK的,因為這不會使得class與C風格的struct有任何本質(zhì)區(qū)別,你完全可以將這樣的class理解為一個C風格的struct + n個全局函數(shù)。
現(xiàn)在,再看看在類中包含內(nèi)部union時會有什么不同。看看下面的程序,并請注意閱讀程序提示:
class TestUnion
{
union DataUnion
{
DataUnion(const char*);
DataUnion(long);
const char* ch_;
long l_;
} data_;
public:
TestUnion(const char* ch);
TestUnion(long l);
};
TestUnion::TestUnion(const char* ch) : data_(ch) // if you want to use initialzing list to initiate a nested-union member, the union must not be anonymous and must have a constructor。
{
}
TestUnion::TestUnion(long l) : data_(l)
{
}
TestUnion::DataUnion::DataUnion(const char* ch) : ch_(ch)
{
}
TestUnion::DataUnion::DataUnion(long l) : l_(l)
{
}
int main (void)
{
return 0;
}
正如上面程序所示,C++中的union也可以包含構(gòu)造函數(shù),但是,這雖然被語言所支持,但實在是一種不佳的編程習(xí)慣,因此,我不打算對上面的程序進行過多的說明。我更推薦如下的編程風格:
class TestUnion
{
union DataUnion
{
const char* ch_;
long l_;
} data_;
public:
TestUnion(const char* ch);
TestUnion(long l);
};
TestUnion::TestUnion(const char* ch)
{
data_。ch_ = ch;
}
TestUnion::TestUnion(long l)
{
data_。l_ = l;
}
int main (void)
{
return 0;
}
它完全是C風格的。
推薦閱讀
- ·Linux字符設(shè)備驅(qū)動框架解析:file_operations的核心作用與實現(xiàn)
- ·廣東朝歌數(shù)碼科技股份有限公司專場招聘會
- ·深化產(chǎn)教融合,共筑技能人才培養(yǎng)新生態(tài) —— 廣州華立學(xué)院到訪粵嵌從化校區(qū)為深化產(chǎn)教
- ·校企合作新突破 | 粵嵌科技與三亞學(xué)院共探產(chǎn)教融合新路徑
- ·粵嵌科技入選國家級職業(yè)數(shù)字展館聯(lián)合建設(shè)單位,賦能計算機程序設(shè)計員高技能人才培養(yǎng)
- ·嵌入式實時操作系統(tǒng)的性能優(yōu)化與實現(xiàn)路徑
- ·校企攜手賦能教育!粵嵌科技助力海南科技職業(yè)大學(xué)探索 AGI 時代教學(xué)新范式
- ·嵌入式系統(tǒng)中的低功耗設(shè)計策略與實現(xiàn)路徑
- ·深圳市軒宇軟件開發(fā)有限公司專場招聘會
- ·嵌入式系統(tǒng)中的代碼空間優(yōu)化:策略與實踐