假設我們有個 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 ...
沒有留言:
張貼留言