儘量使用“引用常量”傳遞函數參數

默認情況下, C++ 爲函數傳入和傳出對象是採用傳值方式的(這是由 C語言繼承而來的特徵)。除非你明確使用其他方法,函數的形式參數總會通過複製實在參數的副本來創建,並且,函數的調用者得到的也是函數返回值得一個副本。這些副本是由對象的拷貝構造函數創建的。這使得“傳值”成爲一項代價十分昂貴的操作。

下面向你介紹正確的方法,那就是:通過引用常量傳遞參數: bool (const Student&s);  這裏Student是一個類名。
這 樣做效率會提高很多:由於不會創建新的對象,所以就不會存在構造函數或析構函數的調用。改進的參數表中的const 是十分重要的:Student 對象是以引用形式傳入的,有必要將其聲明爲 const 的,因爲如果不這樣,調用者就需要關心傳入的 Student 對象有可能會被修改。

揭 開 C++ 編譯器的面紗,你將會發現引用通常情況下是以指針的形式實現的,所以通過引用傳遞通常意味着實際上是在傳遞一個指針。因此,如果傳遞一個內建數據類型的對象(比如 int ),傳值會被傳遞引用更爲高效。那麼,對於內建數據類型,當你在傳值和傳遞常量引用之間徘徊時,傳值方式不失爲一個更好的選擇。迭代器和 STL 中的函數對象都是如此,這是因爲它們設計的初衷就是更適於傳值,這是C++ 的慣例。實現迭代器和函數對象的人員有責任考慮複製時的效率問題和截斷問題.

內建數據類型體積較小,所以一些人得出這樣的結論:所有體積較小的類型都適合使用傳值,即使它們是用戶自定義的。這是一個不可靠的推理。僅僅通過一 個對象體積小並不能判定調用它的拷貝構造函數的代價就很低。許多對象——包括大多數 STL 容器——其中僅僅包含一個指針和很少量的其它內容,但是複製這樣的對象的同時,它所指向的所有內容都需要複製。這將會是一件十分昂貴的事情。

即 使體積較小的對象的拷貝構造函數不會帶來昂貴的開銷,它也會引入性能問題。一些編譯器對內建數據類型和用戶自定義數據類型是分別對待的,即使它們的原始表示方式完全相同。比如說一些編譯器很樂意將一個單純的 double 值放入寄存器中,這是語言的常規,但將僅包含一個 double 值的對象放入寄存器時,編譯器就會報錯了。當你遇到這種事情時,你可以使用引用傳遞這類對象,因爲編譯器此時一定會將指針(引用的具體實現)放入寄存器中。

小型用戶自定義數據類型不適用於傳值方式還有一個理由,那就是:作爲用戶自定義類型,它們的大小並不是固定的。現在很小的類型在未 來的版本中可能會變得很大,這是因爲它的內部實現方式可能會改變。即使是你更改了 C++ 語言的具體實現都可能會影響到類型的大小。比如,在我編寫上面的示例的時候,一些對標準庫中 string 實現的大小竟然達到了另一些的七倍。

總體上講,只有內建數據類型、 STL 迭代器和函數對象類型適用於傳值方式。對於所有其它的類型,都應該遵循本條款中的建議:使用引用常量傳參,而不是傳值。

牢記在心 :

儘量使用引用常量傳參,而不是傳值方式。因爲傳引用更高效,而且可以避免“截斷問題”。
對於內建數據類型、 STL 迭代和函數對象類型,這一規則就不適用了,對它們來說通常傳值方式更實用。

 

參考資料: 《Effective c++

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章