轉載請註明文章出處: https://tlanyan.me/special-me...
C++
類中有幾個特殊的非靜態成員函數,當用戶未定義這些函數時,編譯器將給出默認實現。C++11
前有四個特殊函數,C++11
引入移動語義特性,增長了兩個參數爲右值的特殊函數。這六個函數分別是:ios
默認構造函數指不須要參數就能初始化的構造函數。包含無參和全部參數有默認值兩種類型的構造函數。c++
複製構造函數指使用該類的對象做爲參數的構造函數。能夠有其餘參數,但必須提供默認值。ide
重載等號=
,將該類的對象賦值給已定義對象。函數
沒啥可說的。this
C++11
新增,該類的右值對象爲參數的構造函數,其他同複製構造函數。code
同複製賦值運算符,惟一不一樣是參數爲右值。對象
看定義容易迷糊,上代碼就會很清晰:ci
#include <iostream> #include <string> class Foo { public: std::string s; // 默認構造函數 Foo() { std::cout << "default constructor" << std::endl; } // 複製構造函數 Foo(const Foo& foo) { std::cout << "copy constructor" << std::endl; s = foo.s; } // 複製賦值運算符 Foo& operator=(const Foo& foo) { std::cout << "copy assignment operator" << std::endl; s = foo.s; return * this;} // 移動構造函數 Foo(Foo&& foo) { std::cout << "move constructor" << std::endl; s = std::move(foo.s); } // 移動賦值運算符 Foo& operator=(Foo&& foo) { std::cout << "move assignment operator" << std::endl; s = std::move(foo.s); return *this;} }; int main() { Foo foo1; Foo foo2(foo1); foo1 = foo2; Foo foo3(std::move(foo1)); foo2 = std::move(foo3); }
用g++
或者clang
編譯,加上-fno-elide-constructors -std=c++0x
選項。執行程序輸出以下:get
default constructor copy constructor copy assignment operator move constructor move assignment operator
結果是咱們預期的。須要注意的是Foo foo3 = foo1
的形式會調用複製構造函數,不會調用複製賦值運算符。緣由是Foo foo3 = xxx
聲明和定義一個新對象,而賦值是做用在已定義對象。移動賦值運算符同理。編譯器
C++11
新增了=default
和=delete
函數修飾符,提示編譯器使用默認或者刪除默認的特殊函數。須要注意的是這兩個修飾符只能修飾上述特殊函數,用戶能夠用其對特殊函數進行裁剪。一個例子:
struct Test { // 使用默認構造函數 Test() = default; // 刪除複製賦值運算符 Test& operator=(const Test& test) = delete; // 使用默認析構函數 ~Test() = default; };