4 回答

TA貢獻(xiàn)1852條經(jīng)驗 獲得超7個贊
C ++ 11的經(jīng)驗法則:
通過按值時,除
你不需要對象的所有權(quán)和一個簡單的別名會做,在這種情況下你通過
const
引用傳遞,你必須改變對象,在這種情況下,使用非
const
左值引用傳遞,您將派生類的對象作為基類傳遞,在這種情況下,您需要通過引用傳遞。(使用以前的規(guī)則來確定是否通過
const
引用傳遞。)
幾乎從不建議通過指針傳遞??蛇x參數(shù)最好表示為a std::optional
(boost::optional
對于較舊的std libs),并且通過引用完成別名。
C ++ 11的移動語義使得即使對于復(fù)雜對象,傳遞和返回值也更具吸引力。
C ++ 03的經(jīng)驗法則:
通過const
引用傳遞參數(shù),除非
它們將在函數(shù)內(nèi)部進(jìn)行更改,并且此類更改應(yīng)反映在外部,在這種情況下,您將通過非
const
引用傳遞該函數(shù)應(yīng)該是可調(diào)用的,沒有任何參數(shù),在這種情況下,你通過指針傳遞,以便用戶可以傳遞
NULL
/0
/nullptr
; 應(yīng)用先前的規(guī)則來確定是否應(yīng)該通過指向const
參數(shù)的指針它們是內(nèi)置類型,可以通過復(fù)制傳遞
它們是在函數(shù)內(nèi)部將被改變并且這些變化應(yīng)不被外部的反射,在這種情況下,可以通過復(fù)制通過(一個替代方法是,根據(jù)前述規(guī)則,以通過和使函數(shù)的內(nèi)部副本)
(這里,“按值傳遞”被稱為“按副本傳遞”,因為按值傳遞總是在C ++中創(chuàng)建一個副本03)
還有更多,但這些初學(xué)者的規(guī)則會讓你走得更遠(yuǎn)。

TA貢獻(xiàn)1934條經(jīng)驗 獲得超2個贊
C ++和Java中的調(diào)用約定存在一些差異。在C ++中,從技術(shù)上講,只有兩種約定:按值傳遞和按引用傳遞,一些文獻(xiàn)包括第三次傳遞指針約定(實際上是指針類型的值傳遞)。最重要的是,您可以將const-ness添加到參數(shù)的類型中,從而增強(qiáng)語義。
通過引用傳遞
通過引用傳遞意味著該函數(shù)將在概念上接收您的對象實例而不是它的副本。該引用在概念上是調(diào)用上下文中使用的對象的別名,并且不能為null。在函數(shù)內(nèi)執(zhí)行的所有操作都適用于函數(shù)外部的對象。此約定在Java或C中不可用。
按值傳遞(并按指針傳遞)
編譯器將在調(diào)用上下文中生成對象的副本,并在函數(shù)內(nèi)使用該副本。在函數(shù)內(nèi)執(zhí)行的所有操作都是對副本完成的,而不是外部元素。這是Java中基本類型的約定。
它的一個特殊版本是將指針(對象的地址)傳遞給函數(shù)。函數(shù)接收指針,并且應(yīng)用于指針本身的任何和所有操作都應(yīng)用于副本(指針),另一方面,應(yīng)用于解除引用指針的操作將應(yīng)用于該內(nèi)存位置的對象實例,因此該函數(shù)可能有副作用。使用指向?qū)ο蟮闹羔槀鬟f值的效果將允許內(nèi)部函數(shù)修改外部值,如使用pass-by-reference,并且還允許可選值(傳遞空指針)。
這是C函數(shù)需要修改外部變量時使用的約定,以及Java中使用引用類型的約定:引用被復(fù)制,但引用的對象是相同的:引用/指針的更改在外部不可見該函數(shù),但對指向內(nèi)存的更改是。
將const添加到等式中
在C ++中,您可以在定義不同級別的變量,指針和引用時為對象分配常量。您可以將變量聲明為常量,可以聲明對常量實例的引用,并且可以定義所有指向常量對象的指針,指向可變對象的常量指針和指向常量元素的常量指針。相反,在Java中,您只能定義一個級別的常量ness(final關(guān)鍵字):變量的類型(基本類型的實例,引用類型的引用),但是您不能定義對不可變元素的引用(除非類本身是不可變的)。
這在C ++調(diào)用約定中廣泛使用。當(dāng)對象很小時,您可以按值傳遞對象。編譯器將生成一個副本,但該副本不是一個昂貴的操作。對于任何其他類型,如果函數(shù)不會更改對象,則可以將引用傳遞給該類型的常量實例(通常稱為常量引用)。這不會復(fù)制對象,而是將其傳遞給函數(shù)。但同時編譯器將保證在函數(shù)內(nèi)部不更改對象。
經(jīng)驗法則
這是一些要遵循的基本規(guī)則:
首選基本類型的傳值
對于其他類型的引用,首選引用傳遞
如果函數(shù)需要修改參數(shù),請使用pass-by-reference
如果參數(shù)是可選的,請使用pass-by-pointer(如果不應(yīng)修改可選值,則為常量)
這些規(guī)則還有其他小的偏差,第一個是處理對象的所有權(quán)。當(dāng)使用new動態(tài)分配對象時,必須使用delete(或其[]版本)對其進(jìn)行解除分配。負(fù)責(zé)銷毀對象的對象或函數(shù)被視為資源的所有者。當(dāng)在一段代碼中創(chuàng)建動態(tài)分配的對象,但是所有權(quán)被轉(zhuǎn)移到另一個元素時,通常使用pass-by-pointer語義,或者如果可能的話使用智能指針。
邊注
重要的是要堅持C ++和Java引用之間差異的重要性。在C ++中,引用在概念上是對象的實例,而不是對象的訪問者。最簡單的例子是實現(xiàn)交換功能:
// C++class Type; // defined somewhere before, with the appropriate operationsvoid swap( Type & a, Type & b ) { Type tmp = a; a = b; b = tmp;}int main() { Type a, b; Type old_a = a, old_b = b; swap( a, b ); assert( a == old_b ); assert( b == old_a ); }
上面的交換函數(shù)通過使用引用來更改其參數(shù)。Java中最接近的代碼:
public class C { // ... public static void swap( C a, C b ) { C tmp = a; a = b; b = tmp; } public static void main( String args[] ) { C a = new C(); C b = new C(); C old_a = a; C old_b = b; swap( a, b ); // a and b remain unchanged a==old_a, and b==old_b }}
Java版本的代碼將在內(nèi)部修改引用的副本,但不會在外部修改實際的對象。Java引用是沒有指針?biāo)阈g(shù)的C指針,它們通過值傳遞給函數(shù)。

TA貢獻(xiàn)1815條經(jīng)驗 獲得超13個贊
有幾種情況需要考慮。
參數(shù)修改(“out”和“in / out”參數(shù))
void modifies(T ¶m);// vsvoid modifies(T *param);
這種情況主要是關(guān)于樣式的:你想讓代碼看起來像call(obj)還是call(&obj)?但是,有兩點是重要的:下面是可選的情況,并且您希望在重載運算符時使用引用。
......和可選的
void modifies(T *param=0); // default value optional, too// vsvoid modifies();void modifies(T ¶m);
參數(shù)未修改
void uses(T const ¶m);// vsvoid uses(T param);
這是一個有趣的案例。經(jīng)驗法則是“便宜復(fù)制”類型是通過值傳遞的 - 這些通常是小類型(但并非總是) - 而其他類型則由const ref傳遞。但是,如果您需要在函數(shù)內(nèi)復(fù)制,則應(yīng)按值傳遞。(是的,這暴露了一些實現(xiàn)細(xì)節(jié).C'est le C ++。)
......和可選的
void uses(T const *param=0); // default value optional, too// vsvoid uses();void uses(T const ¶m); // or optional(T param)
所有情況之間的差異最小,因此請選擇最適合您生活的方式。
Const by value是一個實現(xiàn)細(xì)節(jié)
void f(T);void f(T const);
這些聲明實際上是完全相同的功能! 當(dāng)傳遞值時,const純粹是一個實現(xiàn)細(xì)節(jié)。 試試看:
void f(int);void f(int const) { /* implements above function, not an overload */ }typedef void NC(int); // typedefing function typestypedef void C(int const);NC *nc = &f; // nc is a function pointerC *c = nc; // C and NC are identical types
- 4 回答
- 0 關(guān)注
- 828 瀏覽
添加回答
舉報