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