2011-08-29 30 views
8

我在看C++ 11的新功能,其中一個令我困惑,因爲我找不到在真實世界中使用它的方法。刪除和默認功能實際世界範例

它的刪除和默認功能,有沒有人有它的使用的真實世界的例子,或者它只是其中一個功能,只是增加了一些糖?

回答

8
struct A 
{ 
    A(const A& arg) : data(arg.data) 
    { 
    do_something_special(); 
    } 

    // by writing copy constructor, we suppress the generation of 
    // implicit default constructor A::A() 

    int data; 
}; 

void foo1() 
{ 
    A a; // does not work, since there's no default constructor 
} 

比方說,我們的默認構造函數沒有做什麼特別的事情,是(或多或少)等於給編譯器生成一個。我們可以通過編寫我們自己的默認構造函數(這可能會很麻煩,如果我們班有很多非靜態成員)修理,或使用= default語法:

struct A 
{ 
    A() = default; 
    A(const A& arg) : data(arg.data) 
    { 
    do_something_special(); 
    } 

    int data; 
}; 

刪除功能是非常有用的,當我們希望禁止使用特定的重載或模板特化,或者僅限於禁止複製(或移動)對象。

void foo(char c) {} 
void foo(int i) = delete; // do not allow implicit int -> char conversion 

當你想禁止複製(即線程對象),通常慣用的方法是申報私人拷貝構造函數沒有實現(是的,或者使用boost ::不可複製)。雖然這適用於大多數情況,但有時您可能會遇到一些模糊的鏈接器錯誤。試想一下:

struct A 
{ 
    A() = default; 

    friend void foo(); 

private: 
    A(const A&); 
}; 

void foo() 
{ 
    A a; 
    A b(a); // results in linker error in gcc 
} 

製作A(const A&)刪除,我們避免潛在的連接錯誤,使我們的意圖(禁止複製)很清楚。

9

用戶聲明的特殊成員函數不是微不足道的。如果一個類有任何不平凡的特殊成員函數,那麼這個類不是POD。因此,這種類型的POD:

struct S { 
    S() = default; 
    S(int) { } 
}; 

但這種類型不是POD:

struct S { 
    S() { } 
    S(int) { } 
}; 
+0

@Christian的例子:如果我們只是有'的struct {S(INT){}};','的S(INT)的存在下將'禁止隱式聲明的默認構造函數。 –

+0

POD的規則已經在C++ 0x/11中放寬了,所以你的第二個例子也是C++ 0x/11中的POD。例如,您還可以使用新特徵 :: is_pod來檢查自己是否具有靜態斷言。 – David

+0

@大衛:POD的規則確實放寬了,但第二個'S'仍然不是POD。 POD結構必須是一個平凡的類。一個普通的類必須有一個簡單的默認構造函數。用戶提供的默認構造函數不是微不足道的。第二個'S'有一個用戶提供的默認構造函數,因此不是POD。 –

1

對於您想要防止複製或直接實例化的類(例如,您想要執行get_instance()函數的單例),您可以使用已刪除的函數。你冷漠也使用刪除來防止你的構造函數的某些變化。

如果您希望編譯器生成的任何隱式生成的構造函數,默認情況下很有用。例如,如果您創建自定義參數構造函數,編譯器將不會生成默認的無參數,因此您可以要求使用default關鍵字爲其生成。

在這裏看到上述

http://www2.research.att.com/~bs/C++0xFAQ.html#default