1. 程式人生 > >從Java到C++——union的使用方法

從Java到C++——union的使用方法


你是否記得union這個東西,在上大學的時候我們用的是潭浩強的《C語言程式設計》,裡面把它譯作是共用體。“共用體”。儘管翻譯得特別彆扭,但卻正好說明了它的特性和用途。

聯合union。也有翻譯成共用體的是一種特殊的結構(或說類)

一個union能夠有多個數據成員,可是在隨意時刻僅僅有一個成員有值。

Union具有下面幾個特點:

1.一個union能夠有多個不同型別的資料成員。 但在某一時刻僅僅有一個成員有值(即僅僅有一個成員是有效的)

 給union的某個成員賦值後,該union的其他成員就成沒有定義的狀態了。例如以下演示樣例:

// 測試1
union Token
{
    char cVal;      //char 型別
    int nVal;       //int型別
    double dVal;    //double型別
};

void PrintToken(const Token& t)
{
    cout << "char:   " << t.cVal << endl;
    cout << "int:    " << t.nVal << endl;
    cout << "double: " << t.dVal << endl;
}

void TestUnion1()
{
    cout << "Print first:"<< endl;
    Token t;
    t.cVal = 'k';
    PrintToken(t);

    cout << endl << "Print second:"<< endl;
    t.nVal = 5;
    PrintToken(t);
    cout << endl;

    cout << endl << "Print third:"<< endl;
    t.dVal = 10.2;
    PrintToken(t);
}
結果例如以下:



2.分配給一個union物件的儲存空間,至少要能容納它的最大的資料成員(即一個union的儲存空間至少要為其各個成員的資料型別中佔位元組數最大的一個成員的位元組大小)

例如以下演示樣例:

//測試2
union Token
{
    char cVal;      //char 型別。 1 個位元組
    int nVal;       //int型別。 4個位元組
    double dVal;    //double型別, 8個位元組
};

union Token2
{
  short snVal;      //2個位元組
  int nVal;         //4個位元組
};

union Token3
{
  int nVal;         //4個位元組
  float fVal;       //4個位元組
  long lVal;        //4個位元組
  char arr[20];     //20個位元組
};

void TestUnion2()
{
    cout << "size of Token: " << sizeof(Token) << endl;
    cout << "size of Token2:" << sizeof(Token2) << endl;
    cout << "size of Token3:" << sizeof(Token3) << endl;
}
結果例如以下:



3.假設一個union結構中有多個同樣型別的資料成員,則這些資料成員會有同樣的值。

union應該是依據成員佔用的記憶體最大的資料型別的大小分配一段記憶體空間。無論你使用的是那個成員變數,記憶體空間地址和大小都同樣。當然以上就是依據測試的樣例個人進行的判斷,在這個樣例中char的空間首地址輸出有問題,可能跟作業系統有關係。我用的是UbuntuLinux作業系統,例如以下演示樣例:

//測試3
union Token4
{
    unsigned char cVal1;
    unsigned char cVal2;
    short int snVal;
    int nVal;
    long lVal;
    long long llVal;
    double dVal;
    double dVal2;
};

void PrintToken4(const Token4& t)
{
    cout << "char1:    " << t.cVal1 << "\t\t\t" << &t.cVal1 << endl;
    cout << "char2:    " << t.cVal2 << "\t\t\t" << &t.cVal2 << endl;
    cout << "short int:" << t.snVal << "\t\t\t" << &t.snVal << endl;
    cout << "int:      " << t.nVal << "\t\t" << &t.nVal << endl;
    cout << "long:     " << t.lVal << "\t\t" << &t.lVal << endl;
    cout << "long long:" << t.llVal << "\t" << &t.llVal << endl;
    cout << "double1:  " << t.dVal << "\t\t" << &t.dVal << endl;
    cout << "double2:  " << t.dVal2 << "\t\t" << &t.dVal2 << endl;
}

void TestUnion4()
{
    cout << "Print first:"<< endl;
    Token4 t;
    t.cVal1 = 'A';
    PrintToken4(t);

    cout << endl << "Print second:"<< endl;
    t.nVal = 255;
    PrintToken4(t);
    cout << endl;

    cout << endl << "Print third:"<< endl;
    t.dVal = 10.2;
    PrintToken4(t);
}
結果例如以下:




4.C++的早期版本號中(C++11標準之前)。union不能含有定義了拷貝建構函式或拷貝控制成員的類型別成員。但在C++11標準之後取消了這一限制。能夠含有類的成員,如string及自定義的類。含有拷貝建構函式或拷貝控制成員的類型別成員的union比較複雜,能夠去參考C++11標準的相關文件。