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

            99麻豆久久久国产精品免费| 久久精品国产半推半就| 久久精品不卡| 女同久久| 久久中文字幕一区二区| 国产精品中文久久久久久久| 久久精品国产亚洲精品2020| 久久本道综合久久伊人| 亚洲欧美日韩久久精品第一区| 久久99热只有频精品8| 久久久久国产精品麻豆AR影院 | 9999国产精品欧美久久久久久| 国产精品青草久久久久福利99| 色综合久久无码中文字幕| 97久久精品人人澡人人爽| 久久国产精品77777| 亚洲性久久久影院| 久久成人国产精品一区二区| 精品久久久久久中文字幕人妻最新| 亚洲国产综合久久天堂| 久久免费高清视频| 国产一区二区精品久久| 亚洲第一极品精品无码久久| 久久影院午夜理论片无码| 国产精品18久久久久久vr| 久久久国产99久久国产一| 欧美久久亚洲精品| 久久99国产精品成人欧美| 久久精品国产只有精品2020| 亚洲va久久久噜噜噜久久| 久久久精品国产免大香伊 | 久久男人中文字幕资源站| 久久亚洲国产中v天仙www| 久久精品国产只有精品2020| 久久不射电影网| 国产99精品久久| 久久夜色精品国产亚洲| 国内精品伊人久久久久影院对白| 久久高潮一级毛片免费| 色综合久久88色综合天天 | 漂亮人妻被中出中文字幕久久|