c語言入門到c++使用高手:深入學習C++之類 (五)

第三章 類

第五節 拷貝構造函數

  • 默認情況下,類對象的拷貝是每個成員變量逐個拷貝

  • 如果一個類的構造函數的第一個參數,是所屬類類型的引用,如果還有其他額外參數,那麼這個額外的參數都有默認值,
    則這個構造函數就叫做拷貝構造函數,函數默認參數必須放在函數聲明中,除非該函數沒有函數聲明

  • 拷貝構造函數:會在一定的時機,被系統自動調用

  • 拷貝構造函數又叫做複製構造函數

1. 拷貝構造函數

  • 建議拷貝構造函數第一個參數總是帶着const

  • 拷貝構造函數一般不要聲明成explicit

  • 成員變量逐個拷貝的功能因爲我們自己定義的拷貝構造函數的存在而丟失了作用,或者說我們自己的"拷貝構造函數"
    取代了系統默認的每個成員變量逐個拷貝的這種行爲

  1. 如果沒有爲類定義一個拷貝構造函數,編譯器就會幫我們定義一個"合成拷貝構造函數"

  2. 如果是編譯器給我們合成的拷貝構造函數,這個合成拷貝構造函數一般也是將類中的成員逐個拷貝到正在創建的對象中
    每個成員的類型決定其拷貝方式,如果成員變量是整型,就直接把值拷貝過來,如果成員變量是類類型,那麼就會調用這個類的拷貝構造函數

  3. 如果自己定義了拷貝構造函數,那麼就取代了系統合成的拷貝構造函數,這個時候,就必須要在自己的拷貝構造函數中給類成員賦值,以免出現類成員沒有被賦值就使用的情況發生

還有一些情況會發生拷貝構造函數的情形

  • 將一個對象作爲實參傳給一個非引用類型的的形參

  • 從一個函數中返回一個對象的時候會調用拷貝構造函數(windows會,linux不會?),LZ做實驗並不會啊,
    查看地址發現返回的地址是和函數中臨時變量的地址相同,所以沒有調用拷貝構造函數

  • time.h

//
// Created by felaim on 2020/5/26.
//

#ifndef LESSION_PART_TWO_TIME_H
#define LESSION_PART_TWO_TIME_H

class Tmpclass {

public:
    Tmpclass() {
        std::cout << "執行了構造函數 Tmpclass()" << std::endl;
    }

    Tmpclass(Tmpclass &tmpclass) {
        std::cout << "執行了拷貝構造函數 Tmpclass(Tmpclass &tmpclass)" << std::endl;
    }
};

class Time2 {

public:
    Time2();

    // 拷貝構造函數
    Time2(const Time2 &temtime);
//    Tmpclass cl;

public:
    int Hour;
    int Minute;
    int Second{0};
};
#endif //LESSION_PART_TWO_TIME_H

  • time.cpp
//
// Created by felaim on 2020/5/26.
//
#include <iostream>
#include "Time.h"


Time2::Time2() {
    Hour = 12;
    Minute = 59;
    Second = 59;
    std::cout << "執行了構造函數Time2::Time2()" << std::endl;
}

Time2::Time2(const Time2 &temptime) {
    std::cout << "執行了拷貝構造函數Time2::Time2(Time2 &temtime, int a)" << std::endl;
    Hour = temptime.Hour;
    Minute = temptime.Minute;
    Second = temptime.Second;

}
  • main.cpp
#include <iostream>
#include "Time.h"

using namespace std;

void func(Time2 tmptime) {
    return;
}

Time2 func2() {
    Time2 tmp;
    return tmp;
}

int main() {
    //生成對象時,會調用類的構造函數的
    Time2 mytime;
    cout << "mytime: " << mytime.Hour << ":" << mytime.Minute << ":" << mytime.Second << endl;

    //調用了拷貝構造函數
//    Time2 mytime1 = mytime;
//    Time2 mytime2(mytime);
//    Time2 mytime3{mytime};
//    Time2 mytime4 = {mytime};
//    Time2 mytime5;
//    mytime5 = mytime;


    //調用了拷貝構造函數
//    func(mytime);

//經測試,在linux下並沒有調用拷貝構造函數
    Time2 res = func2();
    return 0;
}

關於c語言入門到c++使用高手的完整章節在這篇博客中,建議收藏!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章