2011-01-07 34 views
1

當const值傳遞給對象的構造函數時,是否應該通過引用或值傳遞它們?
構造函數和初始化函數的所有教科書示例都按值傳遞,但這對我來說似乎效率低下。應該通過引用或值傳遞常量構造函數嗎?

如果按值傳遞並且參數立即用於初始化成員變量,是否創建了兩個副本?這是編譯器會自動處理的東西嗎?

class Point { 
public: 
    int x; 
    int y; 
    Point(const int _x, const int _y) : x(_x), y(_y) {} 
}; 

int main() { 
    const int a = 1, b = 2; 
    Point p(a,b); 
    Point q(3,5); 

    cout << p.x << "," << p.y << endl; 
    cout << q.x << "," << q.y << endl; 
} 

class Point { 
public: 
    int x; 
    int y; 
    Point(const int& _x, const int& _y) : x(_x), y(_y) {} 
}; 

編譯和做同樣的事情,但它是正確的?

+1

有一個[gotW文章(#6)](http://www.gotw.ca/gotw/006.htm),講述你何時應該/不應該使用`const`。 – 2011-01-07 23:53:01

回答

1

您在傳遞參考值和傳遞值之間選擇此處。請注意,這些功能簽名是相同的。

Point(int x, int y); 

Point(const int x, const int y); 

從一個呼叫者點參數是否被修改或不作爲參數時通過值傳遞副本總是讓不要緊。

如果您想要在構造函數外初始化一個引用或指向該實際對象的指針,如果您只需要它的值,則傳遞值通常是可取的,除非複製對象的代價太昂貴。對於int,情況絕非如此。

2

對於通過值傳遞的簡單類型很好,您只需複製幾個字節的數據。但對於更復雜的類型,比如向量和字符串,最好傳遞一個const引用。如果你不需要它的副本,複製一個大的字符串或向量是很浪費的。

+0

我知道這個副本不是什麼大不了的,但嚴格來說,額外的副本是完全不必要的,應該避免嗎?這個對象只是爲了說明,但是說你必須在高性能應用程序中創建數以百萬計的對象。對於這樣一個微不足道的構造函數,額外的副本可能會導致整個操作的指令調用次數增加一倍!當然,除非編譯器足夠聰明才能刪除冗餘副本。 – Mike 2011-01-07 23:56:14

+0

我相信大多數編譯器會優化這一點到一個副本 – GWW 2011-01-08 00:01:57

0

像int這樣簡單的東西應該按值傳遞。

如果你有一個大的對象,那麼通過引用傳遞將是有意義的,因爲它避免了不必要的副本。

請注意,如果您的對象是可變的,那麼在傳遞引用或副本之間存在語義差異 - 在前一種情況下,您將看到原始的更改,而在後一種情況下,您不會。即使您已將其聲明爲對const的引用,情況也是如此。

1

按照值而不是按照引用傳遞像int這樣的小基本類型可能更可取。如果我沒有記錯,引用在後臺實現爲隱藏指針(即傳入地址並自動解除引用)。這意味着您仍然會承擔複製和取消引用指針的開銷(在某些體系結構中與int的大小相同)。

通過引用傳遞給const對於較大的用戶定義類型肯定更有意義,因爲它爲您節省了潛在的昂貴複製操作。

相關問題