C++ 快速導覽 - 類別 copy 建構函數

假設我們有個 Demo 類別 (class) ,先建立 Demo 型態的變數 (variable) d1 ,然後宣告同是 Demo 型態的變數 d2 ,並且直接把 d1 指派給 d2 ,如下

Demo d1(p1);
Demo d2 = d1;


這麼寫是沒問題的,因為 d1 複製給 d2 的過程當中會啟動 copy 建構函數 (constructor) ,利用 copy 建構函數完成整個過程,而且就算我們沒有自己寫出 copy 建構函數的話,編譯器 (compiler) 也會主動幫我們加上一個。


可是當 Demo 有成員 (member) 是指標 (pointer) 的話會出現一些問題,當我們改變 d2 的指標成員,使用預設的 copy 建構函數會連帶改變 d1 的指標成員 ,這就不會是我們希望的結果了。


因此我們需要自行設計 copy 建構函數,舉一個完整例子如下
#include <iostream>
#include <string>

class Demo {
public:
    Demo(std::string s) {
        std::cout << "constructor called.." << std::endl;
        aPtr = new std::string;
        *aPtr = s;
    }
                 
    Demo(const Demo &obj) {
        std::cout << "copy constructor called.." << std::endl;
        aPtr = new std::string;
        *aPtr = *obj.aPtr;
    }
    
    void setA(std::string s) {
        *aPtr = s;
    }
    
    void do_something() {
        std::cout << *aPtr << std::endl;
    }

private:
    std::string *aPtr;
    
};

int main(void) {
    Demo d1("There is no spoon.");
    d1.do_something();
    Demo d2 = d1;
    d2.do_something();
    
    d1.setA("What's truth?");
    d1.do_something();
    d2.do_something();

    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:classdemo16.cpp
    功能:示範 C++ 程式
    作者:張凱慶
    時間:西元 2013 年 1 月 */


copy 建構函數在第 12 行,需要 const 的參考 (reference) 當參數 (parameter)
Demo(const Demo &obj) {
    std::cout << "copy constructor called.." << std::endl;
    aPtr = new std::string;
    *aPtr = *obj.aPtr;
}


編譯執行結果如下



要完整的解決指標成員的相關問題,還要重載指派運算子與設計解構函數。


中英文術語對照
類別class
變數variable
建構函數constructor
編譯器compiler
成員member
指標pointer
參考reference
參數parameter


您可以繼續參考
類別


相關目錄
回 C++ 快速導覽
回 C++ 教材
回首頁


參考資料
C++ reference
cplusplus.com
Cprogramming.com C++ Tutorial

C++ Primer, Fourth Edition, Stanley B. Lippman...

沒有留言: