为什么通过const引用而不是通过值? [英] Why pass by const reference instead of by value?

查看:106
本文介绍了为什么通过const引用而不是通过值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我的理解:当你传递值,该函数做一个本地副本的传递参数,并使用;当函数结束时,它超出范围。当你通过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引用避免复制对象。那么在什么情况下复制对象好?我的意思是,为什么不使用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 不引用同一个对象;因此,在写入 b 之后,必须重新读取 a 的值,以防万一。在第二种形式中, 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引用而不是通过值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆