2014-10-20 80 views
1

我知道通過const引用傳遞結構比value更有效,但是如果我想對臨時傳遞的值進行更改,而對於函數的其餘部分,則該怎麼做。不會阻止對結構進行任何更改?換句話說,我如何在函數中對結構進行臨時更改,同時仍然通過const引用傳遞它?C++通過Const來傳遞結構參考

+6

所以你想它是常量,你想改變它? – John3136 2014-10-20 06:00:55

+0

基本上是的,我聽說結構應該總是通過const引用傳遞來節省內存。但是,如果const引用完全防止了臨時變化,也許我被誤導了。 – Travis 2014-10-20 06:06:55

回答

4

您可以製作本地副本,但在這種情況下,傳遞值的方式會更好(不太詳細)。

+0

誠然,如果您需要複印件,請複印一份。按價值傳遞是正確的。 – 2014-10-20 06:04:28

0

如果您打算只更改一個或兩個結構成員,那麼 如果您複製這些結構成員而不是複製所有結構,則會更好。 否則您可以使用按值傳遞,也可以製作本地副本。但在某些情況下,複製是昂貴的。

0

如果你真的渴望你也可以使用const_cast

void foo(my_very_expensive_to_copy_type const& bar) 
{ 
    auto a = const_cast<my_very_expensive_to_copy_type&>(bar); 

    // (i) change the object 
    // (ii) do something else  
    // (iii) restore changes  
} 

然而,並沒有真正意義。如果你想改變它,你應該通過非const引用或值來傳遞它。在後一種情況下,您也不需要恢復原始狀態,但副本可能很昂貴。

+0

除非'my_very_expensive_type'有兩個拷貝構造函數(一個接受一個const引用,另一個接受非const引用),const_cast沒有做任何有意義的使用方式。 – 2014-10-20 06:31:11

0

您需要製作副本的原因是,當您收到一個const引用時,您正在接收查看數據而無法修改它的功能。如果你想在一個函數中臨時修改這些數據的一部分,你必須問問自己這些修改後的值將被存儲在哪裏。由於您不擁有原始內存位置,因此您需要爲此目的製作副本。

您有怎樣使這個副本兩種選擇:

  1. 按值傳遞數據給函數(編譯器將會爲您創建一個副本)
  2. 接收基準,使內的複製功能手動

如果你要保持無論什麼原因,數據的原始值,選擇選項2。例如,跟蹤對象的變化:

void f(const S & originalData) 
{ 
    S copy(originalData); 
    // modify the copy... 

    int delta = copy.someVal - originalData.someVal; 
    // etc.. 
} 

如果您不需要這樣做,請使用選項1!你將有隻有一個變量名來跟蹤,你會不小心做出修改您的本地副本,然後從原始數據讀取錯誤的值:

void f(const S & originalData) 
{ 
    S myData(originalData); 

    // do stuff... 
    myData.field += 100; 

    // want to access the modified field but accidentally read the original! 
    doSomethingImportant(originalData.field); 
} 

如果你有一個長期混亂的功能,這可能會發生。

所以:更喜歡選項1,除非你想跟蹤更改。