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

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

            對union的進一步認識與一些深層應用

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

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

            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(
            大衛注:我想不出來大于的情況).

            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不同的是,所有的成員變量共享同一存儲空間(最大的那一個成員類型的大小),這使得它具有多變的特性,可以在不同成員中任意切換,而無需借助強制類型轉換,但這也使得你不能把它當作一個成員變量進行修改而不影響到另一成員變量;
            2.
            union也可以有構造/析構函數,也可以包含訪問標識符,但不能包含虛函數或靜態成員變量/方法.

            關于使用union時需要注意的一些問題,可以參考我的前一篇文章:<(大衛的閱讀筆記)C++中使用union的幾點思考>.
            下面談談一些比較有意思并且有意義的union的應用.
            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應用的人,肯定都用過它.不知你注意過沒有,它包含了一個很有趣的union,union的各成員具有相同的大小,分別代表同一信息的不同表現形式.你在進行程序設計的時候也可以利用這一特性來提供同一信息的不同表現形式,不過要注意,在進行跨平臺應用時,字節順序的影響可能給你造成一些不必要的麻煩.

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

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

            #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
            ).因為匿名聯合不使用點運算符,所以包含在匿名聯合內的元素必須是數據,不允許有成員函數,也不能包含私有或受保護的成員;
            2
            ).全局匿名聯合必須是靜態(static)的,否則就必須放在匿名名字空間中.

            附注:
            對匿名union的概念,你或許有些陌生,但對于Windows應用的開發人員,有一個經常用到的結構中就包含了匿名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進行類型轉換
            前面已經說過,union具有多變的特性,可以在不同成員中任意切換,而無需借助強制類型轉換,下面舉例說明這一點(其實1已經很好地說明了這一點):

            #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;
            }


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

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

            關于利用引用進行類型轉換,可參考<引用在強制類型轉化的應用>.

             

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

            # re: union的進一步認識與一些深層應用

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

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

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

            # re: union的進一步認識與一些深層應用

            你的文章寫的很好,總結得不錯

            2005-05-05 13:34 | peak

            # re: union的進一步認識與一些深層應用

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

            2005-10-29 00:51 | youngs

            # re: union的進一步認識與一些深層應用

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

            2007-12-13 11:52 | cc

            # re: union的進一步認識與一些深層應用

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

            2008-03-03 15:44 | 大衛的思維空間

             

             

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

            亚洲另类欧美综合久久图片区| 情人伊人久久综合亚洲| 国产女人aaa级久久久级| 久久久女人与动物群交毛片 | 无码超乳爆乳中文字幕久久| 亚洲国产精品综合久久一线 | 久久综合鬼色88久久精品综合自在自线噜噜| 99精品久久精品| 国产精品久久久久天天影视| 久久精品水蜜桃av综合天堂| 久久久无码精品亚洲日韩蜜臀浪潮 | 久久久精品国产Sm最大网站| 国产精品无码久久综合网| 亚洲成色999久久网站| 精品久久久久久国产三级| 久久精品18| 亚洲成av人片不卡无码久久 | 国产精品久久久久天天影视 | 久久青青草原精品国产不卡| 日本久久久久久久久久| 狠狠精品久久久无码中文字幕| 久久久精品国产免大香伊| 久久大香香蕉国产| 精品无码久久久久久久久久| 麻豆av久久av盛宴av| 久久精品国产99久久久| 国产精品一区二区久久精品无码 | 久久久无码精品亚洲日韩软件| 亚洲国产成人乱码精品女人久久久不卡| 久久久久久精品久久久久| 久久精品草草草| 久久综合九色综合网站| 色综合久久88色综合天天| 无夜精品久久久久久| 久久精品国产亚洲AV香蕉| 久久996热精品xxxx| 色婷婷综合久久久中文字幕| 久久精品无码一区二区三区日韩 | 久久这里只有精品视频99| 久久国产精品成人片免费| 亚洲国产天堂久久久久久|