C++類中的特殊成員函數

轉載請註明文章出處: https://tlanyan.me/special-me...

C++類中有幾個特殊的非靜態成員函數,當用戶未定義這些函數時,編譯器將給出默認實現。C++11前有四個特殊函數,C++11引入移動語義特性,增長了兩個參數爲右值的特殊函數。這六個函數分別是:ios

  1. 默認構造函數

    默認構造函數指不須要參數就能初始化的構造函數。包含無參全部參數有默認值兩種類型的構造函數。c++

  2. 複製構造函數

    複製構造函數指使用該類的對象做爲參數的構造函數。能夠有其餘參數,但必須提供默認值。ide

  3. 複製賦值運算符

    重載等號=,將該類的對象賦值已定義對象函數

  4. 析構函數

    沒啥可說的。this

  5. 移動構造函數

    C++11新增,該類的右值對象爲參數的構造函數,其他同複製構造函數code

  6. 移動複製運算符

    複製賦值運算符,惟一不一樣是參數爲右值對象

看定義容易迷糊,上代碼就會很清晰: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;
};

參考

  1. https://en.cppreference.com/w...
  2. https://stackoverflow.com/que...
相關文章
相關標籤/搜索