2016-10-06 86 views
4

此前C++ 11,我看到這樣的代碼:使類不可複製:私人未定義的方法VS刪除方法

class Car { 
public: 
    Car() {} 
private: 
    Car(const Car&); 
    Car& operator=(const Car&); 
}; 

對於C++ 11(或更高版本),我看到這樣的代碼這個:

class Car { 
public: 
    Car() {} 
private: 
    Car(const Car&) = delete; 
    Car& operator=(const Car&) = delete; 
}; 

他們的行爲是否相同?如果沒有,請解釋。

編號:https://ariya.io/2015/01/c-class-and-preventing-object-copy

回答

5

=delete會給更有意義的錯誤消息。有關已刪除函數的錯誤消息告訴您它不存在,並且沒有人可以使用所述構造函數創建對象。說它是私人的並不會提供這些信息 - 它只是說來電者不能稱呼它,不是沒有人能夠。

此外,如果從類內部/外部調用已刪除的構造函數,則其行爲將不同(因爲可以從類內調用私有構造函數)。

https://godbolt.org/g/06R9AQ

5

他們在很多方面相似,但在另外一些國家不同。

考慮以下外部代碼試圖複製類的對象:

int main() { 
    Car c; 
    Car other{c}; 
} 

這兩個版本將導致上述代碼失敗。但是,在這一點上,開發人員會查看界面來查看原因。使用delete版本,顯然Car並不意味着要被複制。使用private版本(至少沒有評論),它引發了懷疑複製構造函數是否可能被偶然置於private部分。

現在考慮成員代碼試圖複製類的對象:

void Car::foo() { 
    Car c; 
    Car other{c}; 
} 

delete版本無法像以前一樣。 private版本是鏈接錯誤。這引發了更大的懷疑 - 忘記定義已經聲明的方法並不罕見。也許這是發生在這裏的事情? delete版本沒有這個問題。

編輯斯科特邁爾斯討論該項目中的Effective Modern C++11不想刪除功能,以私人不確定那些

+1

很好的參考斯科特邁耶斯項目。我昨天晚上發現了它。 – kevinarpe

3

Car& operator=(const Car&) = delete;明確表示「禁止複製分配」。

= delete;也可以作爲比亞的blog描述用於任何功能:

struct Z { 
    // ... 

    Z(long long);  // can initialize with an long long 
    Z(long) = delete; // but not anything less 
}; 
+0

我不知道刪除可以用於其他目的。優秀的加法。 – kevinarpe

3

請注意,您發佈的兩個片段給出了完全同樣的錯誤,那就是一樣的東西:

「 Car(const Car &)'在這方面是私人的

這是因爲您在兩種情況下都將成員方法定義爲私有方法。
如果你想欣賞的差異,你倒是應該有公共delete d拷貝構造函數和複製操作,那就是:

class Car { 
public: 
    Car() {} 
// private: <-- this should not be here 
    Car(const Car&) = delete; 
    Car& operator=(const Car&) = delete; 
}; 

這樣,你將被告知,這些成員方法一直明確有意刪除

使用刪除功能的 '汽車(const的汽車&)'

將它們設置爲私人並不明確地說我想刪除它們
作爲一個例子,它可能已經完成了,你想讓強制你的類的用戶使用工廠方法來創建該類的實例。

無論如何,(不再是這樣)新功能不是免費的,使用它們的方式不是預期的,不會給預期的好處

+0

關於使刪除的方法公開以獲得更好的編譯器錯誤的好處! – kevinarpe

+0

@kevinarpe無障礙功能首先經過驗證。 – skypjack