→ abcxxxx:謝謝你 01/23 14:44
※ 引述《abcxxxx (撐過就是神)》之銘言:
: 開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
: dev c++
: 程式碼(Code):(請善用置底文網頁, 記得排版)
: void Time::print_time( const Time &t )
: .
: .
: .
: int main()
: {
: Time test;
: test.print_time(test); //呼叫print_time函數
: }
: 問題
: 將函數print_time指定給宣告此函數的類別
: 其中掛號裡面的內容我不懂為什麼還要多加上const 謝謝各位
耶,這就要講到參數列四大型態了
以原文為範例,print_time 要傳入一個 Time 物件的話有四種傳法:
1. void Time::print_time( Time t ) //copy 版
2. void Time::print_time( const Time t ) //const copy 版
3. void Time::print_time( Time &t ) //reference 版
4. void Time::print_time( const Time &t ) //const reference 版
理解也非常簡單,當呼叫 test.print_time( test ) 時
可以想像上述四個分別先執行了
1. Time t( test ) //記憶體多存了一個 Time 物件的空間
2. const Time t( test ) //記憶體多存了一個 Time 且 t 不可改
3. Time& t( test ) //記憶體多一個指標讓 t 使用,t 只是 test 的別名
4. const Time& t( test ) //記憶體多一個指標, t 只是 test 的別名
//但不可透過 t 改動 test
再進入函式使用 t
所以如果不傳入參照的話,會多使用一份物件的空間
因此內建型別常常 pass by value,自訂物件比內建型別大的話常常 pass by ref.
這是使用 1.2. 還是使用 3.4. 的差別
不過
3. 有另外一個隱含就是,你可以透過 t 改動 test 的內容
所以用 3. 的時候編譯器會假設你會在函式內改動 t 而牽涉到外面傳入型別的連帶改動
用 4. 則可以避免編譯器有這種假設
有人就會問有什麼差?
差在兩部分
一 3. 的方法不能傳入一個 const Time 物件,但是它功能只是列印,不能傳入不合理
二 3. 的方法不能傳入一個暫時的 Time() 物件,因為編譯器會假設你改動這個暫時物件
而暫時物件再執行完馬上就被銷毀了,改動是沒有意義的。
因此,只是列印的話,建議就用 4. 吧
這裡可以舉一個常有人犯錯的例子,自定義 operator<<:
假設有一個自訂類別 class Vector2D{ private: int r1, r2; };
想要 cout << Vector2D(1, 2) << endl; //印出 <1, 2>
可是定義成 ostream& operator<< ( ostream& out, Vector2D& v2d );
的話上述式子會編譯不過
必須定義成 ostream& operator<< ( ostream& out, const Vector2D& v2d );
歡迎討論
以上
by Aider
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 182.235.36.249