2009-12-09 21 views
3

您好我想知道下面的代碼奇怪的行爲類對象中聯盟

void main() 
{ 
    class test 
    { 
    public: 
     test(){} 
     int k; 
    }; 

    class test1 
    { 
    public: 
     test1(){} 
     int k; 
    }; 

    union Test 
    { 
    test t1; 
    test1 t2; 
    }; 
} 

的原因上面的代碼提示錯誤「錯誤C2620:工會‘測試’:成員‘T1’有用戶定義構造函數或不平凡的默認構造函數

class test 
{ 
    public: 
    //test(){} 
    int k; 
}; 

class test1 
{ 
    public: 
    //test()1{}; 
    int k; 
}; 

union Test 
{ 
    test t1; 
    test1 t2; 
}; 

針對上述情況,沒有錯誤。

我想知道原因。

先謝謝您。 :)

+1

由於已經提供了答案,我只想告訴你,你的第一個代碼對於main來說有一個錯誤的返回類型。 main()應該總是在C/C++中返回一個'int'。 –

+1

只是爲了記錄:C++ 0x將支持在工會內部具有不平凡的構造函數/析構函數的類。 –

+0

同樣在class test1中,ctor被命名爲test而不是test1。 –

回答

15

根據C++標準(§9.5.1,引在其他的答案爲好):

甲聯合可以有成員函數(包括構造和析構),但不虛函數。工會不得有基礎班。聯盟不得用作基礎類。具有不平凡構造函數,非平凡複製構造函數,非平凡析構函數或非平凡複製賦值運算符的類的對象不能是聯合體的成員,也不能是此類對象的數組。如果聯合包含靜態數據成員或引用類型的成員,則該程序不合格。

我第一鏈接到其中規定的Wikipedia article about POD types

在C++甲POD類型被定義爲一個標量型或POD類。 POD類沒有用戶定義的拷貝賦值操作符,沒有用戶定義的析構函數,也沒有非自己的POD的非靜態數據成員。此外,POD類必須是一個聚合,這意味着它沒有用戶聲明的構造函數,沒有私有或非受保護的非靜態數據,沒有基礎和沒有虛函數。該標準包含關於POD如何在C++中表現的聲明。

在某些情況下,C++允許使用僅POD類型。 例如,C++中的聯合體不能包含具有虛函數或非平凡構造函數或析構函數的類。這個限制是強加的,因爲編譯器無法知道應該爲聯合調用哪個構造函數或析構函數。

第二段的第一句話可能會讓你認爲C++只允許POD類型成爲工會的一部分。這是不完全的情況下,因爲它允許以私有成員的一類是一個聯合的一部分:

#include <iostream> 
using namespace std; 

class test1 
{ 
    int i; 
}; 

class test2 
{ 
    int i; 
}; 

union test 
{ 
    test1 t1; 
    test2 t2; 
}; 

int main() 
{ 
    cout << __is_pod(test1) << endl; 
    cout << __is_pod(test2) << endl; 
    cout << __is_pod(test) << endl; 

    return 0; 
} 

上面MSVC++編譯該程序打印出:

0 
0 
1 
+0

@Gregory:忽略我以前的評論,因爲我現在對此不太確定。這就是我如何看待這種情況:標準(在9.5.1中)沒有明確禁止工會中的非POD類型,而是禁止具有不平凡的構造函數/析構函數/賦值運算符的類型。這個定義在一定程度上肯定與POD重疊,但POD的定義也禁止私有成員變量,就我所知,這些變量不會被排除在工會之外。因此工會似乎允許某些非POD。但是,我對此並不完全確定。 –

+0

確實,工會與類型具有私人成員變量,儘管這些不會被視爲POD –

+0

@Charles>我試圖提供更詳細的答案 –

5

C++標準對可放置在聯合中的數據類型有一定的限制。在9.5.1標準如下:

一個 類的一個對象,具有一個非平凡的構造, 一個非平凡拷貝構造,一個 非平凡的析構函數,或一個 非平凡拷貝賦值運算符 不能是聯合體的成員,也不能是這樣的對象的數組。如果工會 包含靜態數據成員或參考類型的成員 程序格式不正確。

因此,你的程序不工作,因爲你明確定義了一個構造函數,因此你的對象違反了非平凡的構造函數限制。

2

在C++中,工會可以不包含具有(非平凡)構造函數或析構函數的類。這是因爲編譯器無法告訴創建或銷燬聯合實例時使用哪個構造函數或析構函數。