問題描述
據我所知:當您按值傳遞時,該函數會生成傳遞參數的本地副本并使用它;當函數結束時,它超出范圍.當您通過 const 引用傳遞時,該函數使用對無法修改的傳遞參數的引用.然而,我不明白為什么一個人會選擇一個而不是另一個,除非在需要修改和返回參數的情況下.如果您有一個沒有返回任何內容的 void 函數,為什么要選擇一個?
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?
所以基本上通過常量引用傳遞避免了復制對象.那么在什么情況下復制對象好呢?我的意思是,如果一直優化性能,為什么不一直使用 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?
推薦答案
有兩個主要考慮因素.一是復制傳遞對象的開銷,二是當對象是本地對象時編譯器可以做出的假設.
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
的主體中,不能假設 a
和 b
沒有引用同一個對象;所以 a
的值必須在寫入 b
后重新讀取,以防萬一.在第二種形式中,a
不能通過寫入 b
來改變,因為它是函數的局部變量,所以這些重新讀取是不必要的.
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
}
例如:在第一個示例中,編譯器可能能夠假設本地對象的值在進行無關調用時不會更改.如果沒有關于 h
的信息,編譯器可能不知道該函數引用的對象(通過引用參數)是否沒有被 h
改變.例如,該對象可能是由 h
修改的全局狀態的一部分.
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
// ...
}
不幸的是,這個例子不是鑄鐵的.可以編寫一個類,例如,在其構造函數中將指向自身的指針添加到全局狀態對象,以便即使是類類型的局部對象也可能被全局函數調用更改.盡管如此,對于本地對象仍然有更多機會進行有效優化,因為它們不能被傳入的引用或其他預先存在的對象直接別名.
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
引用傳遞參數應該選擇在實際需要引用語義的地方,或者只有在潛在別名的成本被復制參數的成本超過時才作為性能改進.
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.
這篇關于為什么通過 const 引用而不是通過值傳遞?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!