簡體   English   中英

CPP const函數參數說明

[英]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引用,因為對ab的賦值可以視為修改。 在上面的函數中,引用非常有用,並且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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM