• <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

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

            對union的進一步認識與一些深層應(yīng)用

            雖然平時在程序開發(fā)時較少使用union,雖然當初學C語言時,union章被老師略過沒有介紹,雖然,自認為自己對union的認識已經(jīng)足夠,但是,在寫完上一篇文章<(大衛(wèi)的閱讀筆記)C++中使用union的幾點思考>之后,網(wǎng)上的討論驅(qū)使我對這一基本的語言特性又投入了一些精力去關(guān)注,并寫成了此文.

            下面以MSDN中關(guān)于union的概述作為開頭,這好像有些無聊,不過,有時候看specification的東西可以給我們很多提示,當我們從應(yīng)用的角度去關(guān)注一樣東西的時候,很多更深層次的考慮被我們忽略了.所以,看下去,里面有些東西可能正是你忽略了的.

            union
            union
            [tag] { member-list } [declarators];

            [
            union] tag declarators;

            The union keyword declares a union type and/or a variable of a union type.

            A union is a user-defined data type that can hold values of different types at different times. It is similar to a structure
            except that all of its members start at the same location in memory. A union variable can contain only one of its members at
            a time. The size of the union is at least the size of the largest member(
            大衛(wèi)注:我想不出來大于的情況).

            For related information, see class, struct, and Anonymous Union.

            Declaring a Union

            Begin the declaration of a union with the union keyword, and enclose the member list in curly braces:

            union
            UNKNOWN    // Declare union type
            {
               char
               ch;
               int
                i;
               long
               l;
               float
              f;
               double
            d;
            }
            var1;          // Optional declaration of union variable
            Using a Union

            A C++ union is a limited form of the class type. It can contain access specifiers (public, protected, private), member data,
            and
            member functions, including constructors and destructors. It cannot contain virtual functions or static data members. It
            cannot be used as a base class, nor can it have base classes. Default access of members in a union is public.

            A C union type can contain only data members.

            In C, you must use the union keyword to declare a union variable. In C++, the union keyword is unnecessary:

            Example 1

            union
            UNKNOWN var2;   // C declaration of a union variable
            UNKNOWN var3;         // C++ declaration of a union variable
            Example 2

            A variable of a union type can hold one value of any type declared in the union. Use the member-selection operator (.) to access a member of a union:

            var1.i = 6;           // Use variable as integer
            var2.d = 5.327;       // Use variable as double

            為了避免對上述文字有稍許的歪曲,我故意沒有翻譯它,但在此對其進行一些歸納:
            1.
            union是一種特殊的struct/class,是一種可用于容納多種類型的類型,但與struct/class不同的是,所有的成員變量共享同一存儲空間(最大的那一個成員類型的大小),這使得它具有多變的特性,可以在不同成員中任意切換,而無需借助強制類型轉(zhuǎn)換,但這也使得你不能把它當作一個成員變量進行修改而不影響到另一成員變量;
            2.
            union也可以有構(gòu)造/析構(gòu)函數(shù),也可以包含訪問標識符,但不能包含虛函數(shù)或靜態(tài)成員變量/方法.

            關(guān)于使用union時需要注意的一些問題,可以參考我的前一篇文章:<(大衛(wèi)的閱讀筆記)C++中使用union的幾點思考>.
            下面談?wù)勔恍┍容^有意思并且有意義的union的應(yīng)用.
            1.
            in_addr

            struct
            in_addr {
              union
            {
                      struct
            { u_char s_b1,s_b2,s_b3,s_b4; }   S_un_b;
                      struct
            { u_short s_w1,s_w2; }            S_un_w;
                      u_long                                   S_addr;
              }
            S_un;
            };


            對于上面的struct,寫過socket應(yīng)用的人,肯定都用過它.不知你注意過沒有,它包含了一個很有趣的union,union的各成員具有相同的大小,分別代表同一信息的不同表現(xiàn)形式.你在進行程序設(shè)計的時候也可以利用這一特性來提供同一信息的不同表現(xiàn)形式,不過要注意,在進行跨平臺應(yīng)用時,字節(jié)順序的影響可能給你造成一些不必要的麻煩.

            2.
            匿名union
            匿名union是沒有名稱和聲明列表的union,這跟'__unnamed' union不是一回事,它的聲明形式如下:
            union
            { member-list } ;

            匿名union僅僅通知編譯器它的成員變量共享一個地址,而變量本身是直接引用的,不使用通常的點號運算符語法.也正因此,匿名union與同一程序塊內(nèi)的其它變量具有相同的作用域級別,需注意命名沖突.
            請看下面的例子:

            #include <iostream.h>

            struct
            DataForm
            {

                enum
            DataType { CharData = 1, IntData, StringData };
                DataType type;

                // Declare an anonymous union.
                union
                {

                    char
              chCharMem;
                    char
            *szStrMem;
                    int
               iIntMem;
                };

                void
            print();
            };


            void
            DataForm::print()
            {

              
            // Based on the type of the data, print the
                // appropriate data type.
                switch( type )
                {

                case
            CharData:
                    cout << chCharMem;
                    break
            ;
                case
            IntData:
                    cout << szStrMem;
                    break
            ;
                case
            StringData:
                    cout << iIntMem;
                    break
            ;
                }
            }


            此外,匿名union還具有以下約束:
            1
            ).因為匿名聯(lián)合不使用點運算符,所以包含在匿名聯(lián)合內(nèi)的元素必須是數(shù)據(jù),不允許有成員函數(shù),也不能包含私有或受保護的成員;
            2
            ).全局匿名聯(lián)合必須是靜態(tài)(static)的,否則就必須放在匿名名字空間中.

            附注:
            對匿名union的概念,你或許有些陌生,但對于Windows應(yīng)用的開發(fā)人員,有一個經(jīng)常用到的結(jié)構(gòu)中就包含了匿名union,它就是VARIANT,也許你沒有注意它罷了:

            typedef struct
            FARSTRUCT tagVARIANT VARIANT;
            typedef struct
            FARSTRUCT tagVARIANT VARIANTARG;

            typedef struct
            tagVARIANT  {
               VARTYPE vt;
               unsigned short
            wReserved1;
               unsigned short
            wReserved2;
               unsigned short
            wReserved3;
               union
            {
                  Byte                    bVal;                 // VT_UI1.
                  Short                   iVal;                 // VT_I2.
                  long                    lVal;                 // VT_I4.
                  float                   fltVal;               // VT_R4.
                  // ...
               };
            };


            3.
            利用union進行類型轉(zhuǎn)換
            前面已經(jīng)說過,union具有多變的特性,可以在不同成員中任意切換,而無需借助強制類型轉(zhuǎn)換,下面舉例說明這一點(其實1已經(jīng)很好地說明了這一點):

            #include <iostream>
            using namespace std;

            struct
            DATA
            {

                char
            c1;
                char
            c2;
            };


            int
            main()
            {

                union
            { 
                    int
            i; 
                    DATA data;
                }
            _ut;
               
                _ut.i = 0x6162;

                cout << "_ut.data.c1 = " << _ut.data.c1 << endl
                    <<
            "_ut.data.c2 = " << _ut.data.c2 << endl;
               
                return
            0;
            }


            需要提醒你的是,數(shù)據(jù)類型的轉(zhuǎn)換,并非union的專長,只是一個可資利用的特性而已.因為,采用union進行類型間轉(zhuǎn)換極易受平臺影響,如上面的程序采用Intel x86 + Windows 2000 + VC6時輸出為:
            _ut.data.c1 = b
            _ut.data.c2 = a
            (
            :因為Intel CPU的架構(gòu)是Little Endian)
            而在SunSparc,你得到的結(jié)果卻是:
            _ut.data.c1 = 
            _ut.data.c2 =
            (
            :因為采用Big Endian,前兩個字節(jié)為0x0000)

            而即便是在同一平臺上,integer類型與real類型間進行轉(zhuǎn)換時也不要采用union,否則,你會得到令你莫名其妙的結(jié)論(這是由于CPUreal類型的處理方式引起的,該方式在各平臺上有極大區(qū)別,同時,根據(jù)C++ Standard,這種作法會引起"undefined behavior").

            關(guān)于利用引用進行類型轉(zhuǎn)換,可參考<引用在強制類型轉(zhuǎn)化的應(yīng)用>.

             

            posted on 2004-11-26 10:16 大衛(wèi)的思維空間 閱讀(3750) 評論(8)  編輯 收藏

            # re: union的進一步認識與一些深層應(yīng)用

            我想不出來大于的情況
            ---
            還有字節(jié)對齊的情況,和struct一樣

            匿名union我經(jīng)常使用,但我不知道它叫匿名union”,而且還可以放在外邊用,我去試試看,謝謝!

            2004-11-26 22:07 | 周星星

            # re: union的進一步認識與一些深層應(yīng)用

            你的文章寫的很好,總結(jié)得不錯

            2005-05-05 13:34 | peak

            # re: union的進一步認識與一些深層應(yīng)用

            union實際上是一個二進制容器,所以當程序中從不同的角度來解釋這個二進制數(shù)據(jù)的時候非常容易受各種實現(xiàn)細節(jié)的影響,尤其是涉及到這些二進制數(shù)據(jù)在不同平臺和編譯器之間交換的時候。

            2005-10-29 00:51 | youngs

            # re: union的進一步認識與一些深層應(yīng)用

            多謝文章。請教問題:union中的成員類型只能是基本的類型,不能使自己定義的類結(jié)構(gòu)么? 比如說 CMyLine m_Ln?

            2007-12-13 11:52 | cc

            # re: union的進一步認識與一些深層應(yīng)用

            union既然可以包含struct,自然也是可以包含從class的,但是存在諸多限制,同時,很難想象你的應(yīng)用需要在union中包含一個復雜class,如CStringSTLstring

            2008-03-03 15:44 | 大衛(wèi)的思維空間

             

             

            posted on 2008-11-19 21:15 肥仔 閱讀(511) 評論(0)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

            久久国产精品成人影院| 久久久久久亚洲Av无码精品专口 | 亚洲国产精品久久| 大蕉久久伊人中文字幕| 久久亚洲国产精品123区| 久久久久久九九99精品| 久久国产影院| 久久夜色精品国产亚洲| 久久99久国产麻精品66| 久久亚洲精品中文字幕| 欧美久久天天综合香蕉伊| 国产精品久久久久aaaa| 精品久久久无码21p发布| 久久99精品久久久久久9蜜桃| 久久亚洲精品国产精品| 伊人久久大香线蕉无码麻豆| 国产亚洲精久久久久久无码AV| 久久国产精品无码HDAV| 无码人妻精品一区二区三区久久 | 国产精品一区二区久久精品无码 | 久久中文字幕一区二区| 亚洲乱码中文字幕久久孕妇黑人 | 亚洲午夜无码AV毛片久久| 夜夜亚洲天天久久| 久久91精品国产91| 久久久久无码中| 久久久久亚洲精品天堂久久久久久 | 精品久久久久久99人妻| 欧美精品一区二区精品久久 | 精品无码久久久久久久动漫| 久久国产精品久久精品国产| 久久久久99精品成人片直播| 欧美精品福利视频一区二区三区久久久精品 | 少妇人妻综合久久中文字幕| 性做久久久久久久久浪潮| 久久亚洲精品国产精品婷婷| 久久久久久久免费视频| 久久人与动人物a级毛片| 中文字幕乱码人妻无码久久| 伊人久久久AV老熟妇色| 国产高潮国产高潮久久久91 |