1. 程式人生 > 資訊 >美味香甜,聖寶萌多口味巧克力糖果 500g×2 袋 25.6 元

美味香甜,聖寶萌多口味巧克力糖果 500g×2 袋 25.6 元

技術標籤:c++

建構函式

  • *建構函式的作用*

    在建立一個新的物件時,自動呼叫的函式,用來進行“初始化”工作:

    對這個物件內部的資料成員進行初始化。

    *建構函式的特點*

    1)自動呼叫(在建立新物件時,自動呼叫)

    2)建構函式的函式名,和類名相同

    3)建構函式沒有返回型別

    4)可以有多個建構函式(即函式過載形式)

    *建構函式的種類*

    預設建構函式

    自定義的建構函式

    拷貝建構函式

    賦值建構函式

自定義預設建構函式

沒有引數的建構函式,稱為預設建構函式。

  • 合成的預設建構函式

但沒有手動定義預設建構函式時,編譯器自動為這個類定義一個建構函式。

1)如果資料成員使用了“類內初始值”,就使用這個值來初始化資料成員。【C++11】

否則,就使用預設初始化(實際上,不做任何初始化)

  • 自定義預設建構函式

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Student {
    public:
        //自定義的預設建構函式
        Student() {
            name = "無名";
            age = 18;
        }
    
        string get_naem() {
            return name;
        }
        int get_age() {
            return age;
        }
    private:
        string name;
        int age;
    };
    
    int main(void) {
        Student s;
        cout << s.get_naem() << "的年齡是:" << s.get_age() << endl;
        return 0;
    }
    

在這裡插入圖片描述

注意:

只要手動定義了任何一個建構函式,編譯器就不會生成“合成的預設建構函式”

一般情況下,都應該定義自己的建構函式,不要使用“合成的預設建構函式”

【僅當資料成員全部使用了“類內初始值”,才宜使用“合成的預設建構函式”】

自定義過載帶參預設建構函式

#include <iostream>
#include <string>
using namespace std;

class Student {
public:
    //自定義的預設建構函式
    Student() {
        name = "無名";
        age = 18;
    }

    //自定義過載帶參預設建構函式
    Student(const char* _name , int _age) {
        name = _name;
        age = _age;
    }

    string get_naem() {
        return name;
    }
    int get_age() {
        return age;
    }
private:
    string name;
    int age;
};


int main(void) {
    Student s("小明" , 18);
    cout << s.get_naem() << "的年齡是:" << s.get_age() << endl;
    return 0;
}

在這裡插入圖片描述

自定義拷貝建構函式

#include <iostream>
#include <string>
using namespace std;

class Student {
public:
    //自定義的預設建構函式
    Student() {
        name = "無名";
        age = 18;
    }

    //自定義過載帶參預設建構函式
    Student(const char* _name , int _age) {
        name = _name;
        age = _age;
    }

    //自定義拷貝建構函式
    Student(const Student& other) {
        name = other.name;
        age = other.age;
    }

    string get_naem() {
        return name;
    }
    int get_age() {
        return age;
    }
private:
    string name;
    int age;
};


int main(void) {
    Student s("小明" , 18);
    Student s1(s);

    cout << s.get_naem() << "的年齡是:" << s.get_age() << endl;
    cout << s1.get_naem() << "的年齡是:" << s1.get_age() << endl;
    return 0;
}

在這裡插入圖片描述

  • 合成的拷貝建構函式(沒有自己定義拷貝構造)

    合成的拷貝建構函式的缺點: 使用“淺拷貝”

    也就是說,如果類的資料成員有指標,且在建構函式中分配的記憶體,那麼在使用合成的拷貝建構函式的時候,就會進行淺拷貝,也就是直接進行地址拷貝,而不是分配記憶體,那麼這樣的後果是非常嚴重的,兩個指標變數指向著同一塊記憶體

    解決方案就是自己定義拷貝建構函式,在拷貝建構函式中分配記憶體

  • 什麼時候呼叫拷貝建構函式

    \1. 呼叫函式時,實參是物件,形參不是引用型別

    如果函式的形參是引用型別,就不會呼叫拷貝建構函式

    \2. 函式的返回型別是類,而且不是引用型別

    \3. 物件陣列的初始化列表中,使用物件。

賦值建構函式(使用過載運算子來實現)

#include <iostream>
#include <string>
using namespace std;

class Student {
public:
    //自定義的預設建構函式
    Student() {
        name = "無名";
        age = 18;
    }

    //自定義過載帶參預設建構函式
    Student(const char* _name , int _age) {
        name = _name;
        age = _age;
    }

    //自定義拷貝建構函式
    Student(const Student& other) {
        name = other.name;
        age = other.age;
    }

    //賦值建構函式
    Student& operator=(const Student& other) {
        name = other.name;
        age = other.age;
        return *this;
    }

    string get_naem() {
        return name;
    }
    int get_age() {
        return age;
    }
private:
    string name;
    int age;
};


int main(void) {
    //呼叫自定義預設建構函式
    Student s("小明" , 18);
    //呼叫拷貝建構函式
    Student s1(s);
    //呼叫賦值建構函式
    Student s2;
    s2 = s1;

    cout << s.get_naem() << "的年齡是:" << s.get_age() << endl;
    cout << s1.get_naem() << "的年齡是:" << s1.get_age() << endl;
    cout << s2.get_naem() << "的年齡是:" << s2.get_age() << endl;
    return 0;
}

在這裡插入圖片描述