• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見(jiàn)諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            C++中使用union的幾點(diǎn)思考

            大衛(wèi)注:
            這段時(shí)間整理舊資料,看到一些文章,雖然講的都是些小問(wèn)題,不大可能用到,但也算是一個(gè)知識(shí)點(diǎn),特整理出來(lái)與大家共享.與此相關(guān)的那篇文章的作者的有些理解是錯(cuò)誤的,我寫(xiě)此文,也是糾正為了作者的一些錯(cuò)誤認(rèn)識(shí).當(dāng)然,如果我的理解有任何錯(cuò)誤,也懇請(qǐng)大家批評(píng)指正.

            C++
            雖說(shuō)被B.S.稱作一門(mén)新語(yǔ)言,但它畢竟與C有著千絲萬(wàn)縷的聯(lián)系,雖然B.S.一再堅(jiān)持,但我還是愿意把C++看作是C ++.
            我們應(yīng)該按照C中的convention去使用union,這是我這篇文章要給出的觀點(diǎn).雖然C++使得我們可以擴(kuò)展一些新的東西進(jìn)去,但是,我建議你不要那樣去做,看完這篇文章之后,我想你大概也是這么想的.

            C
            由于沒(méi)有類(lèi)的概念,所有類(lèi)型其實(shí)都可以看作是基本類(lèi)型的組合,因此在union中包含struct也就是一件很自然的事情了,到了C++之后,既然普遍認(rèn)為C++中的structclass基本等價(jià),那么union中是否可以有類(lèi)成員呢?先來(lái)看看如下的代碼:

            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è)什么也沒(méi)干的構(gòu)造函數(shù),則一切OK.

            為什么編譯器不允許我們的union成員有構(gòu)造函數(shù)呢?我無(wú)法找到關(guān)于這個(gè)問(wèn)題的比較權(quán)威的解釋,對(duì)這個(gè)問(wèn)題,我的解釋是:
            如果C++標(biāo)準(zhǔn)允許我們的union有構(gòu)造函數(shù),那么,在進(jìn)行空間分配的時(shí)候要不要執(zhí)行這個(gè)構(gòu)造函數(shù)呢?如果答案是yes,那么如果TestUnion的構(gòu)造函數(shù)中包含了一些內(nèi)存分配操作,或者其它對(duì)整個(gè)application狀態(tài)的修改,那么,如果我今后要用到obj的話,事情可能還比較合理,但是如果我根本就不使用obj這個(gè)成員呢?由于obj的引入造成的對(duì)系統(tǒng)狀態(tài)的修改顯然是不合理的;反之,如果答案是no,那么一旦我們今后選中了obj來(lái)進(jìn)行操作,則所有信息都沒(méi)有初始化(如果是普通的struct,沒(méi)什么問(wèn)題,但是,如果有虛函數(shù)呢?).更進(jìn)一步,假設(shè)現(xiàn)在我們的union不是只有一個(gè)TestUnion obj,還有一個(gè)TestUnion2 obj2,二者均有構(gòu)造函數(shù),并且都在構(gòu)造函數(shù)中執(zhí)行了一些內(nèi)存分配的工作(甚至干了很多其它事情),那么,如果先構(gòu)造obj,后構(gòu)造obj2,則執(zhí)行的結(jié)果幾乎可以肯定會(huì)造成內(nèi)存的泄漏.
            鑒于以上諸多麻煩(可能還有更多麻煩),在構(gòu)造union時(shí),編譯器只負(fù)責(zé)分配空間,而不負(fù)責(zé)去執(zhí)行附加的初始化工作,為了簡(jiǎn)化工作,只要我們提供了構(gòu)造函數(shù),就會(huì)收到上面的error.
            同理,除了不能加構(gòu)造函數(shù),析構(gòu)函數(shù)/拷貝構(gòu)造函數(shù)/賦值運(yùn)算符也是不可以加.

            此外,如果我們的類(lèi)中包含了任何virtual函數(shù),編譯時(shí),我們將收到如下的錯(cuò)誤信息:
            error C2621: union '__unnamed' : member 'obj' has copy constructor

            所以,打消在union中包含有構(gòu)造函數(shù)/析構(gòu)函數(shù)/拷貝構(gòu)造函數(shù)/賦值運(yùn)算符/虛函數(shù)的類(lèi)成員變量的念頭,老老實(shí)實(shí)用你的C風(fēng)格struct!
            不過(guò),定義普通的成員函數(shù)是OK,因?yàn)檫@不會(huì)使得classC風(fēng)格的struct有任何本質(zhì)區(qū)別,你完全可以將這樣的class理解為一個(gè)C風(fēng)格的struct + n個(gè)全局函數(shù).

            現(xiàn)在,再看看在類(lèi)中包含內(nèi)部union時(shí)會(huì)有什么不同.看看下面的程序,并請(qǐng)注意閱讀程序提示:

            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ù),但是,這雖然被語(yǔ)言所支持,但實(shí)在是一種不佳的編程習(xí)慣,因此,我不打算對(duì)上面的程序進(jìn)行過(guò)多的說(shuō)明.我更推薦如下的編程風(fēng)格:

            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風(fēng)格的.

            所以,接受這個(gè)結(jié)論吧:
            請(qǐng)按照C中的convention去使用union,盡量不要嘗試使用任何C++附加特性.

            posted on 2004-11-12 09:08 大衛(wèi)的思維空間 閱讀(8069) 評(píng)論(16)  編輯 收藏

            # "比較權(quán)威的解釋", B.S權(quán)威不?可惜你不看他的書(shū)。

            以下摘自《 the c++ programming language 3rd 》,對(duì)為什么union不支持構(gòu)造函數(shù)和析構(gòu)函數(shù),推薦怎么使用unions都有說(shuō)明。

            10.4.12
            Unions [class.union]
            A named union is defined as a struct, where every member has the same address (see §C.8.2). A
            union can have member functions but not static members.
            In general, a compiler cannot know what member of a union is used; that is, the type of the
            object stored in a union is unknown. Consequently, a union may not have members with constructors
            or destructors. It wouldn’t be possible to protect that object against corruption or to guarantee
            that the right destructor is called when the union goes out of scope.
            Unions are best used in lowlevel
            code, or as part of the implementation of classes that keep
            track of what is stored in the union (see §10.6[20]).

            其實(shí)正如在vckbase/c++論壇上我對(duì)你說(shuō)的,想想union的用途就可以了。union的出現(xiàn)是為了解決一組不定類(lèi)型數(shù)據(jù)的空間緊張問(wèn)題,它是為省空間用的,不是為了封裝數(shù)據(jù)和方法。所以我覺(jué)得大衛(wèi)兄太過(guò)于刨根究底了,而忽略了C++的實(shí)用性(實(shí)用性是C/C++的首要設(shè)計(jì)思想)

            2004-11-12 10:18 | 一笑

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考

            謝謝笑兄給出的CPL中的相關(guān)論述.我現(xiàn)在主要關(guān)注的內(nèi)容并非C++(雖然C++是我最喜歡的語(yǔ)言),我在blog上發(fā)布這些文章也只是希望談一下自己對(duì)于某些語(yǔ)言特性或新技術(shù)的認(rèn)識(shí),以期對(duì)后來(lái)者有些許幫助,同時(shí),也希望在與大家的交流中提高自己.
            ^_^,
            也許我真的有點(diǎn)刨根究底,不過(guò)笑兄的關(guān)于"union是為省空間用的"的觀點(diǎn)我不認(rèn)同,雖然,我也看到過(guò)類(lèi)似的說(shuō)法,但是,union怎么可能節(jié)省空間呢?:
            union uT
            {
            int i;
            char c;
            };
            當(dāng)他被作為char使用時(shí),明明浪費(fèi)了空間.
            只是從另一角度出發(fā):把它當(dāng)成一種特殊的struct,struct相比時(shí)才可以勉強(qiáng)說(shuō)是節(jié)省了空間.
            我認(rèn)為union的引入,更多地是提供了一種解決多種型別共同使用同一空間(這與節(jié)省空間是兩回事)的機(jī)制,借助這種機(jī)制,我們可以提供更豐富的語(yǔ)言表現(xiàn)力.
            為此,我決定再寫(xiě)一篇文章,談一些比較有意思/有意義的union的使用,請(qǐng)關(guān)注 & 批評(píng)指正.

            2004-11-13 05:11 | Bill David

            # 對(duì)union的進(jìn)一步認(rèn)識(shí)與一些深層應(yīng)用[TrackBack]

            Ping Back來(lái)自:blog.csdn.net
            Bill David
            引用了該文章,地址:http://blog.csdn.net/billdavid/archive/2004/11/26/195006.aspx

            2004-11-26 18:58 | Bill David

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考

            呵呵,仁者見(jiàn)仁,智者見(jiàn)智。
            但是union的確應(yīng)該是節(jié)省空間使用的。當(dāng)時(shí)的初衷是這樣的。但是后來(lái)就不一定了。3ks 二位。

            2005-04-19 17:38 | 漫天飛舞

            # 今日經(jīng)論壇匿名大俠指點(diǎn),union還有一個(gè)重要的特性

            union不支持繼承。

            特記錄于此。

            2005-04-19 17:59 | Bill David

            # re: union不支持繼承。

            我突然覺(jué)得如果union設(shè)計(jì)為可繼承的也未嘗不可。
            union base
            {
                int mem1;
                char mem2;
            };
            這個(gè)假設(shè)被原實(shí)現(xiàn)者設(shè)計(jì)好了,突然,某天我想在base的基礎(chǔ)上添加一些特性,于是我寫(xiě)
            union derive : base
            {
                short mem 3;
            };
            或許可能實(shí)際意義不大吧!但,如果這么說(shuō),我reinterpret_cast成員mem1呢?union的實(shí)際意義又有多大呢?

            不知道你怎么看?

            2006-05-16 13:35 | 清風(fēng)雨

            # re: union的幾點(diǎn)思考

            又看了你的另一篇union的,可能我比較懶惰的緣故,我只得到一個(gè)結(jié)論: union僅僅只是為了方便。

            2006-05-16 13:49 | 清風(fēng)雨

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考

            這都是些什么?

            2006-05-18 21:35 | 一二三

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考

            看不懂

            2006-05-18 21:36 | 一二三

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考

            union
            {
                struct
                       {
                            string name;
                       }info;
                int  age;
            }information;

            上面的語(yǔ)句可能出錯(cuò),has copy constructor.   難道只有把string -->char *??

            2006-07-07 15:38 | Tmin

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考

            看了文章和回帖,我非常同意一笑兄的看法。我覺(jué)得作者沒(méi)有完全理解節(jié)省空間的指的是如何節(jié)省,例如我們獲取一些信息時(shí),需要把信息數(shù)據(jù)填充到一個(gè)結(jié)構(gòu)中,但是我們需要的信息的數(shù)據(jù)的類(lèi)型會(huì)根據(jù)情況不同而不同,如果我們?yōu)榱送ㄓ玫脑挘赡芫托枰獮樗锌赡艹霈F(xiàn)的類(lèi)型都預(yù)留相應(yīng)的空間來(lái)存儲(chǔ),但是每次只能使用其中一個(gè)有效。其他預(yù)留無(wú)效。這顯然是浪費(fèi)空間的。所以union使得不同類(lèi)型數(shù)據(jù)存放在內(nèi)存的同一個(gè)位置,當(dāng)然這個(gè)空間的大小是能容納所有類(lèi)型的數(shù)據(jù)的。因?yàn)?span lang="EN-US">unicon的數(shù)據(jù)類(lèi)型是運(yùn)行時(shí)決定的,事先并不知道,所以為union做一個(gè)構(gòu)造函數(shù)是沒(méi)有意義的。

            2006-10-17 11:48 | hoodlum

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考

            剛才回的倉(cāng)促,可能有論述不是很恰當(dāng)。但是看了作者的另一篇文章里面引用的英文,論述的也和我本來(lái)的想法是一致的。也就是說(shuō),可以使用union.memberData來(lái)訪問(wèn)成員,但是應(yīng)該注意的是,使用時(shí)只有其中一個(gè)成員才是有意義的。union占用的空間大小是所有成員數(shù)據(jù)大小的最小公倍數(shù)。(因此,轉(zhuǎn)為托管代碼中就可以使用一個(gè)能夠容納union大小的數(shù)據(jù)類(lèi)型來(lái)代替,或者用通用的字節(jié)數(shù)組)

            例如下面的例子(來(lái)自Windows API):
            union
            {    
               DWORD dwOemId;    
               struct {
                             WORD wProcessorArchitecture; 
                             WORD wReserved; 
                          };
              };

            它通常占用4個(gè)字節(jié),因此可以使用托管代碼中的Int32來(lái)代替。
            其中dwOemId是為了向前兼容某些系統(tǒng)版本,當(dāng)前已經(jīng)棄用。這樣,一個(gè)程序?qū)?span lang="EN-US">API
            的調(diào)用可以在不同版本的系統(tǒng)中運(yùn)轉(zhuǎn)良好,處理各自自己需要的數(shù)據(jù)。

             

            posted on 2008-11-21 22:07 肥仔 閱讀(2295) 評(píng)論(1)  編輯 收藏 引用 所屬分類(lèi): C++ 基礎(chǔ)

            評(píng)論

            # re: C++中使用union的幾點(diǎn)思考  回復(fù)  更多評(píng)論   

            # re: (大衛(wèi)的閱讀筆記)C++中使用union的幾點(diǎn)思考
            看了文章和回帖,我非常同意一笑兄的看法。我覺(jué)得作者沒(méi)有完全理解“節(jié)省空間”的指的是如何節(jié)省,例如我們獲取一些信息時(shí),需要把信息數(shù)據(jù)填充到一個(gè)結(jié)構(gòu)中,但是我們需要的信息的數(shù)據(jù)的類(lèi)型會(huì)根據(jù)情況不同而不同,如果我們?yōu)榱送ㄓ玫脑挘赡芫托枰獮樗锌赡艹霈F(xiàn)的類(lèi)型都預(yù)留相應(yīng)的空間來(lái)存儲(chǔ),但是每次只能使用其中一個(gè)有效。其他預(yù)留無(wú)效。這顯然是浪費(fèi)空間的。所以u(píng)nion使得不同類(lèi)型數(shù)據(jù)存放在內(nèi)存的同一個(gè)位置,當(dāng)然這個(gè)空間的大小是能容納所有類(lèi)型的數(shù)據(jù)的。因?yàn)閡nicon的數(shù)據(jù)類(lèi)型是運(yùn)行時(shí)決定的,事先并不知道,所以為union做一個(gè)構(gòu)造函數(shù)是沒(méi)有意義的。

            2006-10-17 11:48 | hoodlum
            ------------------------------------------------
            個(gè)人覺(jué)得hoodlum說(shuō)得非常好!
            2010-05-11 10:55 | Coastline
            中文字幕热久久久久久久| 一本久久a久久精品综合香蕉 | 久久精品亚洲中文字幕无码麻豆| 久久精品视频一| 亚洲精品蜜桃久久久久久| 97久久超碰国产精品2021| 久久久精品视频免费观看 | 久久久久亚洲爆乳少妇无| 久久精品日日躁夜夜躁欧美| 久久精品人成免费| 99久久婷婷国产综合精品草原 | 欧美日韩精品久久久久| 一本久久知道综合久久| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 久久r热这里有精品视频| 青草久久久国产线免观| 97精品伊人久久大香线蕉app| 九九久久精品国产| 久久99精品国产自在现线小黄鸭| 久久精品成人| 精品综合久久久久久97超人 | 久久亚洲精品成人av无码网站| 久久天天躁狠狠躁夜夜不卡| 99久久99久久久精品齐齐| 久久受www免费人成_看片中文 | 午夜久久久久久禁播电影 | 久久精品国产亚洲av日韩 | 国产一区二区三区久久| 久久精品卫校国产小美女| 一级做a爰片久久毛片免费陪| 久久青青草原综合伊人| 2021精品国产综合久久| 久久精品国产亚洲AV麻豆网站| 国产成年无码久久久免费| 中文成人无码精品久久久不卡| 久久精品成人免费观看97| 色综合久久综精品| 久久99久久无码毛片一区二区| 99久久国产主播综合精品| 亚洲国产成人久久综合碰碰动漫3d| 久久伊人精品青青草原高清|