1. 程式人生 > >c++:(各種)建構函式的呼叫方式

c++:(各種)建構函式的呼叫方式

c++的類中有5種值得注意的基本的函式:

  • 無參建構函式
  • 有參建構函式
  • 拷貝建構函式
  • 賦值函式
  • 解構函式

關於解構函式,需要注意的點在上一篇部落格裡面 c++: 是否會自動delete? 也提到過了,在這裡暫時不多說。這篇部落格主要記錄這3個建構函式、1個賦值函式的呼叫方式,希望大家學習之後,不但知道如何呼叫,還可以根據一句話來判斷到底呼叫了幾次建構函式。

可以通過一個例子來說明,假如我現在有一個Animal類,其中為了除錯,我特意在每個建構函式中加入了輸出語句,來看看呼叫的結果:

struct Animal {
    int age;
    string
name; Animal() { // 無參建構函式 cout << "No-args Constructor" << endl; age = -1; name = "Unknown"; } Animal(string name, int age) { // 有參建構函式 cout << "Argumenting Constructor" << endl; this->name = name; this->age = age; } Animal(const
Animal &other) { // 拷貝建構函式 cout << "Copy constructor" << endl; this->name = other.name; this->age = other.age; } Animal& operator=(const Animal &other) { // 賦值函式 cout << "Assigning" << endl; this->name = other.name; this
->age = other.age; } ~Animal() { cout << "Destructor" << endl; } friend ostream& operator<<(ostream &out, const Animal &animal) { out << "Animal[" << animal.name << "]: " << "age=" << animal.age; return out; } };

然後,以下程式碼會演示建立一個例項的多種方式,並且我把每一種建立方式的輸出結果、以及一些思考,以註釋的方式寫出來:

int main() {


    //-----------------無參建構函式-----------------------

    Animal animal01; // 雖然不是很明顯,但是這裡不是使用指標,而是直接操作例項,所以這裡實際上呼叫了無參建構函式。
    cout << animal01 << endl;
    /*
      輸出:
        No-args Constructor
        Animal[Unknown]: age=-1
    */


    Animal animal02(); // 這並不能呼叫無參建構函式!編譯器會當作是某個函式的宣告,所以下面輸出的1也許是函式的地址(暫時沒有深究)。
    cout << animal02 << endl;
    /*
      輸出:
        1
    */


    Animal animal03 = Animal();
    // 注意,這裡可能有人會認為:等號右邊呼叫了預設建構函式,然後因為賦值給左邊所以又呼叫了一次拷貝建構函式,就會認為這樣子會白白浪費掉一個例項。
    // 實際上,根據輸出可以看到,結果並不是上述那樣,而是這個語句整體上只調用了一次無參建構函式。即與“Animal animal03;”效果一樣。
    cout << animal03 << endl;
    /*
      輸出:
        No-args Constructor
        Animal[Unknown]: age=-1
    */

    //----------------------------------------------




    //-----------------有參建構函式-----------------------  

    Animal animal001("Lion", 1);
    cout << animal001 << endl;
    /*
      輸出:
        Argumenting Constructor
        Animal[Lion]: age=1
    */


    Animal animal002 = Animal("Lion", 1);
    // 這裡同上面所說的,整體上僅僅呼叫了一次有參建構函式。
    cout << animal002 << endl;
    /*
      輸出:
        Argumenting Constructor
        Animal[Lion]: age=1
    */

    //----------------------------------------------




    //----------------拷貝建構函式-------------------  

    Animal animal0001 = animal001;
    // 這裡要區分“拷貝建構函式”和“賦值函式”的呼叫時機。前者是宣告和賦值在同一行,後者不是。所以這裡屬於拷貝建構函式。
    cout << animal0001 << endl;
    /*
      輸出:
        Copy constructor
        Animal[Lion]: age=1
    */  

    //-------------------------------------------




    //------------------賦值函式------------------------  

    Animal animal;
    animal = animal0001;
    // 因為這裡animal的宣告和賦值不在同一行,所以編譯器會認為不是拷貝構造,而是一般的賦值語句。
    cout << animal << endl;
    /*
      輸出:
        No-args Constructor
        Assigning
        Animal[Lion]: age=1
    */  

    //-----------------------------------

    return 0;
}


原文地址:https://blog.csdn.net/vitalemon__/article/details/60869721