問題描述
據(jù)我所知:當(dāng)您按值傳遞時,該函數(shù)會生成傳遞參數(shù)的本地副本并使用它;當(dāng)函數(shù)結(jié)束時,它超出范圍.當(dāng)您通過 const 引用傳遞時,該函數(shù)使用對無法修改的傳遞參數(shù)的引用.然而,我不明白為什么一個人會選擇一個而不是另一個,除非在需要修改和返回參數(shù)的情況下.如果您有一個沒有返回任何內(nèi)容的 void 函數(shù),為什么要選擇一個?
From what I understand: when you pass by value, the function makes a local copy of the passed argument and uses that; when the function ends, it goes out of scope. When you pass by const reference, the function uses a reference to the passed argument that can't be modified. I don't understand, however, why one would choose one over the other, except in a situation where an argument needs to be modified and returned. If you had a void function where nothing is getting returned, why choose one over the other?
所以基本上通過常量引用傳遞避免了復(fù)制對象.那么在什么情況下復(fù)制對象好呢?我的意思是,如果一直優(yōu)化性能,為什么不一直使用 const 引用?
So basically passing by const reference avoids copying the object. So in what situations is copying the object good? I mean, why not just use const references all the time if it optimizes performance all the time?
推薦答案
有兩個主要考慮因素.一是復(fù)制傳遞對象的開銷,二是當(dāng)對象是本地對象時編譯器可以做出的假設(shè).
There are two main considerations. One is the expense of copying the passed object and the second is the assumptions that the compiler can make when the object is a a local object.
例如在第一種形式中,在 f
的主體中,不能假設(shè) a
和 b
沒有引用同一個對象;所以 a
的值必須在寫入 b
后重新讀取,以防萬一.在第二種形式中,a
不能通過寫入 b
來改變,因為它是函數(shù)的局部變量,所以這些重新讀取是不必要的.
E.g. In the first form, in the body of f
it cannot be assumed that a
and b
don't reference the same object; so the value of a
must be re-read after any write to b
, just in case. In the second form, a
cannot be changed via a write to b
, as it is local to the function, so these re-reads are unnecessary.
void f(const Obj& a, Obj& b)
{
// a and b could reference the same object
}
void f(Obj a, Obj& b)
{
// a is local, b cannot be a reference to a
}
例如:在第一個示例中,編譯器可能能夠假設(shè)本地對象的值在進行無關(guān)調(diào)用時不會更改.如果沒有關(guān)于 h
的信息,編譯器可能不知道該函數(shù)引用的對象(通過引用參數(shù))是否沒有被 h
改變.例如,該對象可能是由 h
修改的全局狀態(tài)的一部分.
E.g.: In the first example, the compiler may be able to assume that the value of a local object doesn't change when an unrelated call is made. Without information about h
, the compiler may not know whether an object that that function has a reference to (via a reference parameter) isn't changed by h
. For example, that object might be part of a global state which is modified by h
.
void g(const Obj& a)
{
// ...
h(); // the value of a might change
// ...
}
void g(Obj a)
{
// ...
h(); // the value of a is unlikely to change
// ...
}
不幸的是,這個例子不是鑄鐵的.可以編寫一個類,例如,在其構(gòu)造函數(shù)中將指向自身的指針添加到全局狀態(tài)對象,以便即使是類類型的局部對象也可能被全局函數(shù)調(diào)用更改.盡管如此,對于本地對象仍然有更多機會進行有效優(yōu)化,因為它們不能被傳入的引用或其他預(yù)先存在的對象直接別名.
Unfortunately, this example isn't cast iron. It is possible to write a class that, say, adds a pointer to itself to a global state object in its constructor, so that even a local object of class type might be altered by a global function call. Despite this, there are still potentially more opportunities for valid optimizations for local objects as they can't be aliased directly by references passed in, or other pre-existing objects.
通過 const
引用傳遞參數(shù)應(yīng)該選擇在實際需要引用語義的地方,或者只有在潛在別名的成本被復(fù)制參數(shù)的成本超過時才作為性能改進.
Passing a parameter by const
reference should be chosen where the semantics of references are actually required, or as a performance improvement only if the cost of potential aliasing would be outweighed by the expense of copying the parameter.
這篇關(guān)于為什么通過 const 引用而不是通過值傳遞?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!