2010-04-28 152 views
8

我知道如果你寫了void function_name(int & a),那麼函數將不會執行作爲參數傳遞的變量的本地副本。在文獻中也遇到過,爲了說編譯器,你應該寫void void function_name(const int & a),我不想讓作爲參數傳遞的變量被複制。函數參數的區別在C++中爲(const int&)和(int&a)

所以我的問題:這兩種情況有什麼區別(除了「const」確保傳遞的變量不會被函數改變!!!)???

+0

這難道不是'const int的及了'和'INT了',甚至'const int的了'現實點之間的區別?我想知道爲什麼編譯器應該在'const int&a'和'const int a'之間做出區別?還是使用&garantee編譯器不會做一個副本,'const int a'強制它做一個副本?你怎麼能說'離開編譯器選擇'? – kriss 2010-04-28 07:17:15

+0

請參閱這裏:http://stackoverflow.com/questions/2139224/2139254#2139254 – sbi 2010-04-28 07:37:46

+1

@kriss:編譯器不能選擇。考慮你聲明瞭一個函數'void f( int x);'。在聲明的時候,編譯器沒有關於你是否會改變對象的信息。只能看到代碼,它可以斷言代碼不會改變或改變參數。即使如此,如果代碼更改參數,編譯器如何知道是否希望在該函數之外顯示該更改?即使它可以根據定義來決定,編譯器如何考慮僅包含頭部的翻譯單元中的簽名? – 2010-04-28 07:43:36

回答

10

無論何時不需要寫入,您都應該在簽名中使用const。將const添加到簽名有兩個效果:它告訴編譯器,您希望它檢查並確保您不會更改函數內的該參數。第二個效果是,使外部代碼能夠使用自己常量(和臨時)的函數傳遞對象,從而實現同一功能的更多用途。

與此同時,const關鍵字是您的函數/方法文檔的重要部分:函數簽名明確說明您打算如何處理該參數,以及是否安全地傳遞一個對象是另一個對象不變量到你的函數的一部分:你是明確的,你不會搞砸他們的對象。

使用const在您的代碼(函數)中強制執行一組更嚴格的要求:您不能修改對象,但同時對調用方的限制較少,從而使您的代碼更具可重用性。

void printr(int & i) { std::cout << i << std::endl; } 
void printcr(const int & i) { std::cout << i << std::endl; } 
int main() { 
    int x = 10; 
    const int y = 15; 
    printr(x); 
    //printr(y); // passing y as non-const reference discards qualifiers 
    //printr(5); // cannot bind a non-const reference to a temporary 
    printcr(x); printcr(y); printcr(5); // all valid 
} 
7

So my question: what is the difference with this two cases (except that "const" enshures that the variable passes will not be changed by function!!!)???

的區別。

+0

我從複製的角度來看。 – Narek 2010-04-28 07:23:20

+0

@Narek:'const'不影響是否執行復制。按引用傳遞(不管是否使用const)將避免副本。按值傳遞(不使用引用)會導致副本,無論參數是否爲「const」。對'int'使用'const'引用參數通常被認爲是不必要的,因爲在這種情況下,按值傳遞沒有額外的成本。 – 2010-04-28 07:27:33

+0

@Michael:那麼'const int'和'int'呢? – kriss 2010-04-28 09:19:02

1

您聲明差異的權利。

如果要指定該功能可以變化通過(可變)參考指定參數的參數(即用於init_to_big_number(int& i)有疑問時,指定它const

:你也可以制定它。

請注意,不復制參數的好處在於性能,即對於'昂貴'的對象。對於像int這樣的內置類型,編寫void f(const int& i)是沒有意義的。將參考傳遞給變量與傳遞值。

0

它們被用於不同的目的ES。使用const int&傳遞變量可確保您獲得具有更好性能的傳遞複製語義。你被保證被調用的函數(除非它使用const_cast做一些瘋狂的事情)不會修改你傳入的參數而不創建一個副本。 int&在通常有多個函數返回值時使用。在這種情況下,可以使用這些函數來保存函數的結果。

+2

但是你不能通過'const int&'拷貝語義。被調用函數的外部變化將在被調用函數內部可見。這絕對不是通過複製語義傳遞的,它是通過引用傳遞的特徵。 – 2010-04-28 07:16:48

1

有一個在他們可以運行在參數方面有很大的區別, 說你有一個從int類拷貝構造函數,

customeclass(const int & count){ 
    //this constructor is able to create a class from 5, 
    //I mean from RValue as well as from LValue 
} 
customeclass(int & count){ 
    //this constructor is not able to create a class from 5, 
    //I mean only from LValue 
} 

const版本可以在臨時值和非恆定的基本操作版本無法在臨時版本上運行,當你錯過需要使用STL的const時,你會很容易面對問題,但是你會遇到錯誤,告訴它無法找到需要臨時版本的版本。我建議儘可能使用const。

0

我要說的是

void cfunction_name(const X& a); 

允許我引用傳遞給臨時對象如下

X make_X(); 

function_name(make_X()); 

雖然

void function_name(X& a); 

未能實現這一目標。出現以下錯誤 錯誤:從'X'類型的臨時類型'X &'的非常量引用無效初始化

0

遺漏了性能討論,讓代碼說話!

void foo(){ 
    const int i1 = 0; 
    int i2 = 0; 
    i1 = 123; //i gets red -> expression must be a modifiyble value 
    i2 = 123; 
} 
//the following two functions are OK 
void foo(int i) { 
    i = 123; 
} 
void foo(int & i) { 
    i = 123; 
} 
//in the following two functions i gets red 
//already your IDE (VS) knows that i should not be changed 
//and it forces you not to assign a value to i 
//more over you can change the constness of one variable, in different functions 
//in the function where i is defined it could be a variable 
//in another function it could be constant 
void foo(const int i) { 
    i = 123; 
} 
void foo(const int & i) { 
    i = 123; 
} 

使用「常量」需要它具有以下優點: *您可以在我定義的函數改變一個變量i的常量性,在不同的功能 它可能是一個變量 在另一個功能可能是不變的價值。 *您的IDE已經知道我不應該改變。 它迫使你不分配一個值,我

問候 哎呀

相關問題