[英]c++ copy construct parameter passed by value
我希望freeFunct在它自己的對象副本a上做非const的東西。
假設freeFunct需要是一個自由函數,因為在實際代碼中它需要許多不同的參數,從所有這些函數調用幾個公共函數,並且沒有必要使它成為任何類的非靜態成員函數。
我想到了三種不同的宣告方式。
我覺得第三種解決方案更糟糕。
前兩個有什么區別嗎?
還有更好的東西嗎?
void freeFunct1(A a){
a.doStuff();
}
void freeFunct2(const A& a){
A b = a;
b.doStuff();
}
/**users of freeFunct3 are expected
*to give a copy of their variable:
*{
* A b = a;
* freeFunct3(b);
*}
*/
void freeFunct3(A& a){
a.doStuff();
}
第一個是最好的:它允許調用者選擇是復制還是移動他的對象,因此如果調用者不需要保留副本,則可以更有效。
freeFunct1(a); // "a" is copied and not changed
freeFunct1(std::move(a)); // "a" is moved and perhaps changed
第二個類似,但強制副本。
正如你所說,第三個更容易出錯,因為調用者必須知道它會修改參數。
首先, freeFunct3
如果自由函數的語義只是修改其“自己的”對象,則不要執行freeFunct3
。
其次, freeFunct1
和freeFunct2
之間存在差異,這與移動優化 [C ++ 11], 異常安全和可能的代碼大小有關 。
使用freeFunct2
(通過引用到const):
A
的復制結構拋出異常,它將拋出函數體內 。 A
的復制構造函數是內聯的(函數不是),它將在函數體內展開一次 (即使從多個不同的地方調用函數)。 使用freeFunct1
(按值計算):
A
有一個移動構造函數並且你傳遞一個rvalue(例如調用freeFunct1(A(args))
),你可以避免復制。 A
拋出異常,就會拋出在調用點 。 A
的復制(或移動)構造函數被內聯,它將在每個調用站點多次展開。 或者,您可以重載lvalue / rvalue引用以避免不必要地復制rvalues:
void freeFunct4(const A& a){
A b = a;
b.doStuff();
}
void freeFunct4(A&& a){
a.doStuff();
}
IMO,第一個是最好的,最后一個是最差的。
然而,相當多的人已經習慣於通過const引用傳遞他們將默認寫入#2,即使在這種情況下他們需要它試圖避免的副本。
第一個只更改本地副本。 第二個與第一個相同,但有額外的代碼。 第三個將更改a
到主叫方可見freeFunct3
因為它是一個非const引用。 如果在函數上面的注釋中調用,那么它與第二個版本沒有什么不同。
因此,如果您只想修改本地副本,而不將這些更改傳遞給調用者,那么第一個版本就是我推薦的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.