[英]CPP const function parameters explanation
我一直在關注本教程 ,但我無法理解本節。
因此,它說按值傳遞會創建數據的副本,因此效率低下,因為它會創建數據的副本,這很有意義:
string concatenate (string a, string b)
{
return a+b;
}
那么您就可以解決“創建數據副本”問題:
string concatenate (string& a, string& b)
{
return a+b;
}
這很有意義,因為它正在使用引用。
但是我不明白這一點:
string concatenate (const string& a, const string& b)
{
return a+b;
}
其中說:
通過將它們限定為const,禁止該函數修改a或b的值,但實際上可以訪問其值作為引用(參數的別名),而不必創建字符串的實際副本。
為什么不使用第二種方法呢? 在此示例中,是否仍未修改數據? 有人可以給我一個更好的例子嗎?
是否只是出於安全原因?
如果您實際擁有的字符串是const,或者您僅具有const引用,則可以將它們傳遞給此函數:
string concatenate (const string& a, const string& b);
但是您不能將它們傳遞給此函數:
string concatenate (string& a, string& b);
如果您的字符串不是 const,則無論如何都可以將它們傳遞給任一函數。 因此,除了確保您不會無意間修改字符串之外,參數上的const
允許使用更通用的函數,該函數可以接受const或非const參數。
例如:
string concatenate_non_const (string& a, string& b)
{
return a+b;
}
string concatenate_const (const string& a, const string& b)
{
return a+b;
}
int main()
{
std::string s1 = "hello";
std::string s2 = "world";
const std::string cs1 = "hello";
const std::string cs2 = "world";
concatenate_const(s1, s2); // okay
concatenate_const(cs1, cs2); // okay
concatenate_non_const(s1, s2); // okay
concatenate_non_const(cs1, cs2); // error
}
另外,除了聲明為const的對象之外,還有一些臨時對象需要考慮,這些臨時對象不能綁定到非const引用。
concatenate_const("hello", "world"); // okay
concatenate_non_const("hello", "world"); // error
為什么不使用第二種方法呢? 在此示例中,是否仍未修改數據? 有人可以給我一個更好的例子嗎?
在這里,在編寫函數的地方,這沒關系,因為您自己沒有更改參數。
一個更好的例子
在const
引用上使用引用的一個更好的示例是例如帶有swap函數。 以這個為例,它交換2個整數。
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
現在,在上面的示例中,您不能使用const
引用,因為對a
和b
的賦值可以視為修改。 在上面的函數中,引用非常有用,並且const
替代方法無效。
一個不太具體的例子
這是一個不太具體的示例,它說明了與swap(a,b)
函數相同的概念:
void pre_incr(int& a)
{
++a;
}
現在,為什么此函數比swap()
更具體的原因是,您可以像這樣平等地使用按值傳遞:
void pre_incr(int a)
{
return ++a;
}
無論哪種方式,這兩個函數都說明了按const
引用傳遞和按常規引用傳遞以及按值傳遞之間的區別。
只是出於安全原因嗎?
構成編程語言的大部分原因都是“安全原因”,否則我們可能會在匯編之類的代碼中隨意跳轉。
使函數的參數引用const字符串有兩個目的:
考慮這種情況:
string a = "foo", b = "bar";
cout << concatenate(a, b); // "foobar"
你得到你所期望的, 即使你修改了通過串在你的級聯功能。
string a = "foo", b = "bar";
cout << concatenate(a, b);
// some code
string c = "baz";
cout << concatenate(a, c); // "Aaaabaz"
你可能會搜索所有的,“一些代碼”找到修改a
甚至考慮尋找到之前concatenate
...
還要注意,第一個例子(單次使用的參數字符串),就是你很可能在一個單元測試發現concatenate
。
當您在第一個方法中傳遞沒有const且沒有&的字符串時,需要將其復制到效率低下的函數中。 通過引用時,不會復制該引用。 當您通過const引用傳遞時,它避免了復制的效率低下,同時不允許函數修改字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.