C++ 速查手冊 V1.00 - 單元 9.14 - Copy 建構函數




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


    Demo d1(p1);
    Demo d2 = d1;

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


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


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


001 #include <iostream>
002 #include <string>
003
004 class Demo {
005 public:
006    Demo(std::string s) {
007       std::cout << "constructor"
008                 << std::endl;
009       a_ptr = new std::string;
010       *a_ptr = s;
011    }
012
013    Demo(const Demo& obj) {
014       std::cout << "copy constructor"
015                 << std::endl;
016       a_ptr = new std::string;
017       *a_ptr = *obj.a_ptr;
018    }
019     
020    void set_a(std::string s) {
021       *a_ptr = s;
022    }
023     
024    void do_something() {
025       std::cout << *a_ptr
026                 << std::endl;
027    }
028
029 private:
030    std::string *a_ptr;
031 };
032
033 int main() {
034    Demo d1("There is no spoon.");
035    d1.do_something();
036    Demo d2 = d1;
037    d2.do_something();
038
039    d1.set_a("What's truth?");
040    d1.do_something();
041    d2.do_something();
042
043    return 0;
044 }
045  
046 /* Kaiching Chang 
047    u0914.cpp
048    2014-02 */

Copy 建構函數在第 13 行,需要 const 的參考當參數


013 Demo(const Demo& obj) {
014    std::cout << "copy constructor"
015              << std::endl;
016    a_ptr = new std::string;
017    *a_ptr = *obj.a_ptr;
018 }

編譯執行,結果如下


$ g++ u0914.cpp
$ ./a.out
constructor
There is no spoon.
copy constructor
There is no spoon.
What's truth?
There is no spoon.
$

continue ...

沒有留言: