1. 程式人生 > >c++11 default和delete

c++11 default和delete

轉自:https://www.ibm.com/developerworks/cn/aix/library/1212_lufang_c11new/index.html

在函式聲明後加 =default 和 =delete。通過將類的特殊成員函式宣告為 defaulted 函式,可以顯式指定編譯器為該函式自動生成預設函式體。通過將函式宣告為 deleted 函式,可以禁用某些不期望的轉換或者操作符。Defaulted 和 deleted 函式特性語法簡單,功能實用,是對 C++ 標準的一個非常有價值的擴充。

 

C++ 的類有四類特殊成員函式,它們分別是:預設建構函式、解構函式、拷貝建構函式以及拷貝賦值運算子

default:

1、

class X{ 
public: 
 X(int i){ 
   a = i; 
 }     
private: 
 int a; 
}; 
 
X x;  // 錯誤 , 預設建構函式 X::X() 不存在

1編譯出錯的原因在於類 X 已經有了使用者自定義的建構函式,所以編譯器將不再會為它隱式的生成預設建構函式。如果需要用到預設建構函式來建立類的物件時,程式設計師必須自己顯式的定義預設建構函式

2、

class X{ 
public: 
 X(){};  // 手動定義預設建構函式
 X(int i){ 
   a = i; 
 }     
private: 
 int a; 
}; 
 
X x;   // 正確,預設建構函式 X::X() 存在

2 可以看出,原本期望編譯器自動生成的預設建構函式需要程式設計師手動編寫了,即程式設計師的工作量加大了。此外,手動編寫的預設建構函式的程式碼執行效率比編譯器自動生成的預設建構函式低。類的其它幾類特殊成員函式也和預設建構函式一樣,當存在使用者自定義的特殊成員函式時,編譯器將不會隱式的自動生成預設特殊成員函式,而需要程式設計師手動編寫,加大了程式設計師的工作量。類似的,手動編寫的特殊成員函式的程式碼執行效率比編譯器自動生成的特殊成員函式低。

Defaulted 函式的提出

為了解決如清單 3 所示的兩個問題:1. 減輕程式設計師的程式設計工作量;2. 獲得編譯器自動生成的預設特殊成員函式的高的程式碼執行效率,C++11 標準引入了一個新特性:defaulted 函式。程式設計師只需在函式聲明後加上“=default;

”,就可將該函式宣告為 defaulted 函式,編譯器將為顯式宣告的 defaulted 函式自動生成函式體。例如:

3、

class X{ 
public: 
 X()= default; 
 X(int i){ 
   a = i; 
 }     
private: 
 int a; 
}; 
 
X x;

3 中,編譯器會自動生成預設建構函式 X::X(){},該函式可以比使用者自己定義的預設建構函式獲得更高的程式碼效率。 

delete:

4、

class X{            
     public: 
       X(); 
       X(const X&) = delete;  // 宣告拷貝建構函式為 deleted 函式
       X& operator = (const X &) = delete; // 宣告拷貝賦值操作符為 deleted 函式
     }; 
 
 int main(){ 
  X x1; 
  X x2=x1;   // 錯誤,拷貝建構函式被禁用
  X x3; 
  x3=x1;     // 錯誤,拷貝賦值操作符被禁用
 }

 

Defaulted 函式特性僅適用於類的特殊成員函式,且該特殊成員函式沒有預設引數。例如

class X { 
public: 
 int f() = default;      // 錯誤 , 函式 f() 非類 X 的特殊成員函式
 X(int) = default;       // 錯誤 , 建構函式 X(int, int) 非 X 的特殊成員函式
 X(int = 1) = default;   // 錯誤 , 預設建構函式 X(int=1) 含有預設引數
};

Defaulted 函式既可以在類體裡(inline)定義,也可以在類體外(out-of-line)定義。例如:

class X{ 
public:  
  X() = default; //Inline defaulted 預設建構函式
  X(const X&); 
  X& operator = (const X&); 
  ~X() = default;  //Inline defaulted 解構函式
}; 
 
X::X(const X&) = default;  //Out-of-line defaulted 拷貝建構函式
X& X::operator = (const X&) = default;     //Out-of-line defaulted  
    // 拷貝賦值操作符