通过引用传递 c++
我的 C++ 老师告诉我,只有当我不打算更改函数内数组上的任何内容时,才应使用引用调用。 我在程序中传递了一些非常大的向量。所有向量都将在函数内修改。我的矩阵的大小约为 [256*256][256][50]
...
是否有某些特殊原因不在这里使用调用引用?
AFAIK 通过引用调用应该更快并且消耗更少的内存?
My teacher in c++ told me that call by reference should only be used if I'm not going to change anything on the arrays inside the function.
I have some really big vectors that I'm passing around in my program. All the vectors will be modified inside the functions. My matrices are of sizes about [256*256][256][50]
...
Is there some particular reason not to use call-by reference here?
AFAIK call by reference should be way faster and consume less memory?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
除了关于何时以及如何传递非基本类型可能的 const 引用的所有常见讨论之外,数组在这里非常特殊。
由于与 C 的向后兼容性,并且由于您的具体问题:数组可能很大,数组在 C 或 C++ 中永远不会真正按值传递。该数组将衰减为指向第一个元素的指针,因此当您编写时:
编译器实际上正在处理:
无论数组的大小是多少(有两个常见的陷阱:相信
array
是foo
中的一个数组,并且相信它上面有 100 个元素。现在,在 C++ 中,您实际上可以通过引用传递数组,但引用必须是 的。数组的具体类型,包括大小:
有趣的语法告诉编译器该函数将采用恰好包含 100 个
type
类型元素的数组,其优点是编译器可以执行。为您检查大小:现在,问题是您的函数仅适用于恰好包含 100 个元素的数组,并且在某些情况下,您可能希望在不同的数组大小中执行相同的操作。两种解决方案是:模板化函数。在数组的大小中,这将为每个使用的大小提供大小安全的实现——更长的编译时间和二进制大小,为每个不同的大小编译模板——或者使用按值传递语法,这将使数组衰减——大小不安全,必须作为额外参数传递,更少的编译时间和二进制大小。第三种选择是将两者结合起来:
在这种情况下,虽然每种大小都会有一个模板化的
foo
,但编译器很可能会内联调用,并且生成的代码将相当于调用者提供数组和尺寸。真实数组不需要额外的计算和类型安全。现在,数组很少使用引用传递。
Besides all common discussions on when and how to pass by possibly const reference for non-primitive types, arrays are quite special here.
Due to backwards compatibility with C, and there due to your specific problem: arrays can be huge, arrays are never really passed by value in either C or C++. The array will decay into a pointer to the first element, so when you write:
The compiler is actually processing:
Regardless of what the size of the array is (two common pitfalls there: trusting that
array
is an array insidefoo
and believing that it will be guaranteed to be 100 elements on it.Now, in C++ you can actually pass arrays by reference, but the reference must be of the concrete type of the array, that includes the size:
The funny syntax there is telling the compiler that the function will take an array of exactly 100 elements of type
type
. The advantage there is that the compiler can perform size checking for you:Now, the problem is that your function will only work for an array of exactly 100 elements, and in some cases, you might want to perform the same operation in different array sizes. The two solutions are: template the function in the size of the array which will provide a size-safe implementation for each used size --greater compile time and binary size, the template is compiled for every different size-- or using the pass-by-value syntax, which will make the array decay --not safe in size, that must be passed as extra argument, lesser compile time and binary size. A third option is combining both:
In this case, while there will be one templated
foo
for each size, the compiler will most probably inline the call and the generated code would be equivalent to the caller providing the array and size. No extra computations needed and type safety for real arrays.Now, pass-by-reference is very rarely used with arrays.
当您不更改函数内部的某些内容或您更改内容并希望将更改反映到原始数组或不关心更改时,应使用它反映在原始数组中。
如果您不希望函数更改原始数组(您需要在调用后保留原始值)并且被调用函数更改传递参数的值,则不应使用它。
It should be used when you are not changing something inside the function or you change things and want the changes to be reflected to the original array or don't care about the changes to be reflected in the original array.
It shouldn't be used if you don't want your function to change your original array (you need to preserve the original values after the call) and the callee function changes the values of the passed argument.
你的老师错了。如果您需要修改数组,则可以通过引用传递。如果您不想修改某些内容,请通过 const 引用传递。
Your teacher is wrong. If you need to modify arrays, pass by reference is the way to go. If you don't want something modified, pass by const reference.
为了防止意外更改,请使用 pass-by-const-reference;这样,默认情况下*,传入的数组不能被调用的函数更改。
* 可以用
const_cast
覆盖。To prevent accidental changes, use pass-by-const-reference; that way, by default*, the passed-in array can't get changed by the called function.
* Can be overridden with
const_cast
.如果满足以下条件,则可以按引用传递:
当您按引用传递某些内容时,只有指针会传递给函数。如果你传递整个对象,那么你需要复制它,所以它会消耗更多的CPU和内存。
You can pass by reference if:
When you pass something by reference, then only pointer is passed to function. If you pass whole object then you need to copy it, so it will consume more cpu and memory.
一般来说,对象应该始终通过引用传递。否则将生成对象的副本,如果对象很大,这将影响性能。
现在,如果您调用的方法或函数不修改对象,则最好按如下方式声明该函数:
如果您尝试在函数体内修改对象的状态,则会生成编译错误。
还应该注意的是,数组总是通过引用传递。
Generally speaking, objects should always be passed by reference. Otherwise a copy of the object will be generated and if the object is substantially big, this will affect performance.
Now if the method or function you are calling does not modify the object, it is a good idea to declare the function as follows:
This will generate a compile error if you attempt to modify the object's state inside the function body.
Also it should be noted that arrays are always passed by reference.
等一下..我很害怕人们如何回答这个问题。据我所知,数组总是通过引用传递。
此外,您不能明确地说数组参数是引用,因为这将是创建引用数组的语法(这是不允许的)。
那么你是什么意思?
此外,许多人说只有在修改函数内数组的内容时才应该这样做。那么,const 引用呢?
-- 编辑
有人请指出我如何在 C++ 中不通过引用传递数组吗?
-- 编辑
哦,所以你在谈论向量。好的,那么经验法则是:
我错过了什么吗?
-- 编辑
谢谢,德里比亚斯。
Hold on a second.. I'm scared at how people are answering this one. Arrays, as far as I remember, are always passed by reference.
Further, you can't say the array argument is a reference explicitly, as that would be the syntax for creating an array of references (something that's not allowed).
So what do you mean?
Further, many are saying that you should only do that if you modify the contents of the array inside the function. Then, what about reference-to-const?
-- edit
Will somebody please point me out how to not pass an array by reference in C++?
-- edit
Oh, so you're talking about vectors. Okay, then the rules of thumb are:
Did I miss something?
-- edit
void function(int (&array)[100])
) when you want to ensure that the array has a given definite size.Thanks, dribeas.
通常,在入门课程中,他们会告诉您这一点,这样您就不会意外更改您不想更改的内容。
就像如果您通过引用传递 userName,并且不小心将其更改为 mrsbuxley,这可能会导致错误,或者至少会在以后造成混乱。
Usually, in introductory courses, they tell you that so you don't accidentally change something you didn't want to.
Like if you passed in userName by reference, and accidentally changed it to mrsbuxley that probably would cause errors, or at the very least be confusing later on.
我看不出有什么理由不能通过引用传递。或者,您可以传递指针,但我认为有时通过引用传递更好,因为它可以避免空指针异常。
如果你的老师建议这是某种约定,那么如果有意义的话,请随意打破它。您始终可以在函数上方的注释中记录这一点。
I don't see any reason why you can't pass by reference. Alternatively you could pass pointers around, but I think pass by reference is better sometimes as it avoids null pointer exceptions.
If your teacher has suggested this as some kind of convention, then feel free to break it if it makes sense to. You can always document this in a comment above the function.
我们的风格是永远不要按值传递对象,而总是传递引用或 const 引用。我们不仅拥有可以包含数百 MB 数据的数据结构,并且按值传递将成为应用程序杀手,而且如果我们按值传递 3D 点和向量,我们的应用程序也会陷入停滞。
Our house style is to NEVER pass an object by value but to always pass a reference or const reference. Not only do we have data structures that can contain 100s of MB of data and pass by value would be an application killer, but also if we were passing 3D points and vectors by value the our applications would grind to a halt.
通过引用传递对象总是一个不错的选择,但我们需要小心,首先我们必须决定我们的函数的目的/目的是什么?
你必须在这里做出选择,我们是只读取对象的数据还是修改它。
假设你有一个像这样的接口
,你可以修改我们传递的对象的值,但是当你传递敏感数据时这是一场灾难,你可能会丢失原始数据并且无法恢复它,对吗?
因此,C++ 为您提供了一种功能,可以不更改您将其引用传递给函数的对象的值,并且传递对象的 const 引用始终是一个不错的选择,例如,
This保证你的对象的实际值不会改变,但这又取决于你的接口的目的,你是想改变它还是只使用(读取)它
It is always a good choice to pass object by reference but we need to be careful and first we have to decide what is our purpose/ purpose of our function?
You have to make a choice here, whether we are gonna only read the data of an object or modify it.
Suppose you got an interface like
so in this you can modify value an object which we are passing, but it is a disaster when you passing your sensitive data, you might lose you original data and can not revert it, right?
so c++ provides you a functionality to not to change the value of an object whose reference you are passing to a function, and it is always a good choice to pass a
const
reference of an object for e.g.,This guarantees that your actual value of an object is not gonna change, but again it depends on purpose of your interface whether you wanna change it or only use(read) it