2016-03-27 47 views
9

比方說,我有一個類不執行和刪除常用操作符有什麼區別?

class Object 
{ 
public: 
    Object(int i) : num(i) {}; 

    int getNum() const { return num; } 
private: 
    int num; 
}; 

現在,如果我嘗試這樣做

Object obj{ 1 }; 
Object obj2{ 2 }; 
Object obj3 = obj + obj2; //This is wrong 

這是非法的:'Object' does not define this operator or a conversion to a type acceptable to the predefined operator

添加Object operator+(const Object&) = delete;不會改變任何內容,除了錯誤消息:'Object Object::operator +(const Object &)': attempting to reference a deleted function

deletedelete是否只有具有隱式聲明(如賦值運算符和複製/移動構造函數)的運算符才需要,還是它改變了我的情況?

+0

我認爲這是添加到語言的主要原因是防止複製或明確朝。 – karakfa

+0

這就是我的想法,但如果允許的話,就必須有一個原因。 – Rakete1111

回答

8

是否只需要具有隱式聲明(如賦值運算符和複製/移動構造函數)的運算符的刪除操作,還是在我的情況下更改其他任何內容?

否和否。你的情況對於任何這種差異都很重要。

= delete有兩個目的:

1:它強制消除功能這將(可能)否則在那裏。即特殊成員功能。

2:它指定具有該簽名的函數不能被調用。這實質上是#1的泛化。

後者的原型示例用於防止函數參數的隱式轉換。如果你這樣做:

void foo(float val); 
void foo(int) = delete; 

你不能再叫foo(5);您必須使用foo(5.f)。爲什麼?因爲編譯器會看到第二個重載,請查看它與最佳的調用匹配,然後立即失敗,因爲該函數被刪除。

這有時這樣做還有:

void foo(float val); 
template<typename T> void foo(T&&) = delete; 

這確保您可以與實際float調用它。沒有可以從float轉換的類型。

+0

爲什麼在最後一種情況下模板需要右值引用?在我看來,只是一個普通的「模板 void foo(T)= delete」就足夠了。 –

+0

@SamVarshavchik:可能沒有必要。 –

+0

@SamVarshavchik考慮,例如'void g(AbstractClassWithConversionToFloat&x){foo(x); }'。 'void foo(T)= delete;'會產生替換失敗(因爲函數參數類型不能是抽象的)並且不正確地阻止了調用。 –

1

@NicolBolas的anwer是完全可以接受的。這裏有另一個例子來說明,有時候不能不聲明/定義一個函數,因爲別人會這樣做(比如編譯器生成特殊的成員函數),而你的代碼可以調用它(例如通過隱含的構造函數或轉換運算符)。

#include <iostream> 

// your code 
struct Base {}; 

// some teammate 
struct Wrap 
{ 
    /* implicit */ Wrap(Base const& b) {} 
}; 

void fun(Wrap const&) { std::cout << __PRETTY_FUNCTION__ << '\n'; } 

// client code 
int main() 
{ 
    Base b; 
    fun(b); // oops, probably didn't intend to call fun(Wrap const&) 
} 

Live Example輸出void fun(const Wrap &)

現在昔日預C++ 11,你可以聲明,但沒有定義

void fun(Base const&); // no definition provided 

Live Example輸出的鏈接錯誤

從C++ 11開始,您可以明確刪除相同的功能

void fun(Base const&) = delete; // C++11 onwards 

Live Example輸出的編譯器錯誤(比以前的鏈接錯誤更翔實)

main.cpp:20:5: error: call to deleted function 'fun' 
    fun(b); // oops, probably didn't intend to call fun(Wrap const&) 
    ^~~ 
main.cpp:6:6: note: candidate function has been explicitly deleted 
void fun(Base const&) = delete; // C++11 onwards 
    ^
相關問題