2012-04-21 71 views
3

如果所有函數需要做的一個參數是看它的價值與價值,不應該你總是擦肩而過不斷引用該參數?參數傳遞禮儀(C++)const的&

我的一位同事說,它不小的類型無所謂,但我不同意。

那麼,有沒有優勢,做到這一點:

void function(char const& ch){ //<- const ref 
    if (ch == 'a'){ 
     DoSomething(ch); 
    } 
    return; 
} 

在此:

void function(char ch){ //<- value 
    if (ch == 'a'){ 
     DoSomething(ch); 
    } 
    return; 
} 

他們似乎是相同的大小對我說:

#include <iostream> 
#include <cstdlib> 

int main(){ 

    char ch; 
    char& chref = ch; 

    std::cout << sizeof(ch) << std::endl; //1 
    std::cout << sizeof(chref) << std::endl; //1 

    return EXIT_SUCCESS; 
} 

但我不知道這是否總是如此。
我相信我是正確的,因爲它不會產生任何額外的開銷,這是自我記錄。
但是,我想問問社區我的推理和假設是否正確?

+1

你的演示代碼似乎表明'sizeof(ch)'和'sizeof(ch)'是一樣的 - 是你想要的嗎? – 2012-04-21 04:07:38

+1

即使你的意思是'sizeof(chref)'爲其中之一,你仍然會得到相同的大小。但是這並不相關,因爲當你做'sizeof(chref)'時,它實際上告訴你ch的大小。一旦你初始化了一個引用,它的所有操作就好像他們實際上是在引用上完成的一樣。但是這並沒有告訴你任何關於編譯器的魔法,可能會在幕後進行。 – 2012-04-21 04:10:40

+0

@JonathanLeffler修復 – 2012-04-21 04:23:43

回答

2

即使sizeof(chref)相同sizeof(ch),通過參考確實需要在大多數系統上更多的字節傳送字符:雖然標準沒有說具體的關於引用的實施,一個地址(即指針)什麼是定期通過在幕後。通過優化,它可能無所謂。當您編寫模板函數時,不會被修改的未知類型的項目應該始終由const引用傳遞。

至於小類型去,你可以通過值與const預選賽通過他們強調的是,你是不是要通過你的函數的簽名觸摸爭論點:

void function(const char ch){ //<- value 
    if (ch == 'a'){ 
     DoSomething(ch); 
    } 
    return; 
} 
1

的大小是不是與通過相同。結果取決於ABIs調用約定,但sizeof(referenceVariable)產生sizeof(value)

如果一個函數需要處理一個參數是看它的值,你不應該總是通過常量引用傳遞該參數嗎?

這就是做的。我知道人們不同意我的觀點,主張通過價值傳遞小建築物,或者寧願忽略const。按引用傳遞可以添加指令和/或消耗更多空間。我通過這種方式一致性,因爲總是測量的最佳方式來傳遞任何給定的平臺是很多的麻煩來維持的。

沒有超出可讀性優勢(如果這是你的偏好)。性能可能會受到很小的影響,但在大多數情況下不會考慮。

由值傳遞這些小建宏是比較常見的。如果按價值傳遞,則可以const限定定義(獨立於聲明)。

我的建議是,絕大多數團隊應該簡單地選擇一種方式來通過並堅持下去,除非每條指令都計數,否則性能不應該影響。 const永遠不會傷害。

+1

是的。在(*)極不可能的事件中,(a)你的程序不夠快,(b)「不夠快」和「足夠快」之間的差異是通過引用,那麼你可以重新訪問它。在這種情況發生之前,最好儘可能傳達你的意圖。 – Ben 2012-04-21 04:19:24

+0

@絕對+1。我曾經在一些體系結構上對它進行了測量,並得出結論認爲,在我不願下降到組裝的高度優化的性能關鍵程序中,差異並不顯着。 – justin 2012-04-21 04:23:12

0

在我看來,通過const引用傳遞的一般方法是一種很好的做法(但請參閱下面的示例中的一些注意事項)。另一方面,你的朋友是正確的,對於內置類型,通過引用不應該導致任何顯着的性能增益,甚至可能導致邊際性能損失。我來自C背景,所以我傾向於在指針方面考慮引用(儘管存在一些細微的差異),並且在任何平臺上,「char *」將比任何平臺上的「char」更大熟悉。

[編輯:刪除不正確的信息]

底線,在我看來,就是當你傳遞較大的用戶定義類型,並調用函數只需要在不修改他們讀值,通過「類型const &」是一個好習慣。正如你所說,它是自我記錄,並有助於澄清各種內部API的角色。

+1

不存在'const char const&'這樣的事情。 'const'綁定到左邊的值,除非它是第一個單詞,在這種情況下,它綁定到右邊的值。所以你說的是'char const const'。'char const&'大致等價於'char const * const',這意味着一個'const T&'''T const&'(同樣的東西)不能修改這個值。 – 2012-04-21 04:31:00

+0

你是對的。我必須在C++中處理這個問題已經有好幾年了。這可能會編譯IIRC,但它確實是多餘的。感謝您的澄清。我認爲我最近在C中使用指針的工作讓我失望了。 – coydog 2012-04-21 04:35:51

+2

@coydog:如果它是錯誤的,你應該編輯你的文章*刪除*的信息,而不是簡單地說不管它。 – 2012-04-21 04:50:27

2

對於較小的值,創建引用和取消引用的成本很可能大於拷貝它的成本(如果根本不同的話)。當您認爲參考參數幾乎總是作爲指針實現時,尤其如此。如果您只是將您的值聲明爲const(我僅將該值用於輸入並且不會被修改),那麼這兩個文檔同樣適用。我通常只將const值和所有用戶定義/ STL類型的所有標準內置類型製作爲const &

您的sizeof示例存在缺陷,因爲chref只是ch的別名。 sizeof(T)對於任何類型的T都會得到相同的結果。

3

你的同事是正確的。對於小類型(char,int),當變量不被修改時,通過引用傳遞是沒有意義的。按值傳遞會更好,因爲指針的大小(在通過引用傳遞的情況下使用)大約是小類型的大小。

此外,通過價值傳遞,鍵入較少,並且可讀性略高。