在 C++ 中通过引用/值传递
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/410593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pass by Reference / Value in C++
提问by user36064
I would like to clarify the differences between by value and by reference.
我想澄清按值和按引用之间的区别。
I drew a picture
我画了一张图
So, for passing by value,
因此,对于按值传递,
a copy of an identical object is created with a different reference, and the local variable is assigned the new reference, so to point to the new copy
使用不同的引用创建相同对象的副本,并为局部变量分配新引用,因此指向新副本
How to understand the words: " If the function modifies that value, the modifications appear also within the scope of the calling function for both passing by value and by reference "
如何理解这句话:“如果函数修改了那个值,那么修改也会出现在调用函数的范围内,无论是按值传递还是按引用传递”
Thanks!
谢谢!
回答by Johannes Schaub - litb
I think much confusion is generated by not communicating what is meant by passed by reference. When some people say pass by referencethey usually mean not the argument itself, but rather the object being referenced. Some other say that pass by reference means that the object can't be changed in the callee. Example:
我认为不传达通过引用传递的含义会产生很多混乱。当有些人说通过引用传递时,他们通常指的不是参数本身,而是被引用的对象。其他人说通过引用传递意味着不能在被调用者中更改对象。例子:
struct Object {
int i;
};
void sample(Object* o) { // 1
o->i++;
}
void sample(Object const& o) { // 2
// nothing useful here :)
}
void sample(Object & o) { // 3
o.i++;
}
void sample1(Object o) { // 4
o.i++;
}
int main() {
Object obj = { 10 };
Object const obj_c = { 10 };
sample(&obj); // calls 1
sample(obj) // calls 3
sample(obj_c); // calls 2
sample1(obj); // calls 4
}
Some people would claim that 1 and 3 are pass by reference, while 2 would be pass by value. Another group of people say all but the last is pass by reference, because the object itself is not copied.
有些人会声称 1 和 3 是按引用传递的,而 2 是按值传递的。另一组人说除了最后一个都是通过引用传递的,因为对象本身没有被复制。
I would like to draw a definition of that here what i claim to be pass by reference. A general overview over it can be found here: Difference between pass by reference and pass by value. The first and last are pass by value, and the middle two are pass by reference:
我想在这里定义我声称通过引用传递的内容。可以在此处找到对其的一般概述:按引用传递和按值传递的区别。第一个和最后一个是值传递,中间两个是引用传递:
sample(&obj);
// yields a `Object*`. Passes a *pointer* to the object by value.
// The caller can change the pointer (the parameter), but that
// won't change the temporary pointer created on the call side (the argument).
sample(obj)
// passes the object by *reference*. It denotes the object itself. The callee
// has got a reference parameter.
sample(obj_c);
// also passes *by reference*. the reference parameter references the
// same object like the argument expression.
sample1(obj);
// pass by value. The parameter object denotes a different object than the
// one passed in.
I vote for the following definition:
我投票支持以下定义:
An argument (1.3.1) is passed by reference if and only if the corresponding parameter of the function that's called has reference type andthe reference parameter binds directly to the argument expression (8.5.3/4). In all other cases, we have to do with pass by value.
当且仅当被调用函数的相应参数具有引用类型并且引用参数直接绑定到参数表达式 (8.5.3/4) 时,参数 (1.3.1) 才通过引用传递。在所有其他情况下,我们必须处理按值传递。
That means that the following is pass by value:
这意味着以下是按值传递的:
void f1(Object const& o);
f1(Object()); // 1
void f2(int const& i);
f2(42); // 2
void f3(Object o);
f3(Object()); // 3
Object o1; f3(o1); // 4
void f4(Object *o);
Object o1; f4(&o1); // 5
1
is pass by value, because it's not directly bound. The implementation may copy the temporary and then bind that temporary to the reference. 2
is pass by value, because the implementation initializes a temporary of the literal and then binds to the reference. 3
is pass by value, because the parameter has not reference type. 4
is pass by value for the same reason. 5
is pass by value because the parameter has not got reference type. The following cases are pass by reference (by the rules of 8.5.3/4 and others):
1
是按值传递的,因为它没有直接绑定。实现可以复制临时文件,然后将该临时文件绑定到引用。2
是按值传递的,因为实现初始化了文字的临时值,然后绑定到引用。3
是传值,因为参数没有引用类型。4
出于同样的原因,是按值传递的。5
是按值传递,因为参数没有引用类型。以下情况为传参(按8.5.3/4等规则):
void f1(Object *& op);
Object a; Object *op1 = &a; f1(op1); // 1
void f2(Object const& op);
Object b; f2(b); // 2
struct A { };
struct B { operator A&() { static A a; return a; } };
void f3(A &);
B b; f3(b); // passes the static a by reference
回答by Flame
When passing by value:
按值传递时:
void func(Object o);
and then calling
然后打电话
func(a);
you will construct an Object
on the stack, and within the implementation of func
it will be referenced by o
. This might still be a shallow copy (the internals of a
and o
might point to the same data), so a
might be changed. However if o
is a deep copy of a
, then a
will not change.
您将Object
在堆栈上构造一个,并且在func
它的实现中将由o
. 这可能仍然是一个浅拷贝(内部a
和o
可能指向相同的数据),所以a
可能会改变。但是如果o
是深拷贝a
,则a
不会改变。
When passing by reference:
通过引用传递时:
void func2(Object& o);
and then calling
然后打电话
func2(a);
you will only be giving a new way to reference a
. "a
" and "o
" are two names for the same object. Changing o
inside func2
will make those changes visible to the caller, who knows the object by the name "a
".
你只会给出一种新的引用方式a
。" a
" 和 " o
" 是同一个对象的两个名称。更改o
内部func2
将使这些更改对调用者可见,调用者知道名称为“ a
”的对象。
回答by user36064
Thanks so much everyone for all these input!
非常感谢大家的所有这些投入!
I quoted that sentence from a lecture note online: http://www.cs.cornell.edu/courses/cs213/2002fa/lectures/Lecture02/Lecture02.pdf
我从网上的讲义中引用了这句话:http: //www.cs.cornell.edu/courses/cs213/2002fa/lectures/Lecture02/Lecture02.pdf
the first page the 6th slide
第一页第六张幻灯片
" Pass by VALUE The value of a variable is passed along to the function If the function modifies that value, the modifications stay within the scope of that function.
" Pass by VALUE 将变量的值传递给函数 如果函数修改了该值,则修改保留在该函数的范围内。
Pass by REFERENCE A reference to the variable is passed along to the function If the function modifies that value, the modifications appear also within the scope of the calling function.
通过 REFERENCE 将对该变量的引用传递给该函数 如果该函数修改了该值,则该修改也会出现在调用函数的范围内。
"
”
Thanks so much again!
再次非常感谢!
回答by vboctor
I'm not sure if I understand your question correctly. It is a bit unclear. However, what might be confusing you is the following:
我不确定我是否正确理解你的问题。这有点不清楚。但是,以下内容可能会让您感到困惑:
When passing by reference, a reference to the same object is passed to the function being called. Any changes to the object will be reflected in the original object and hence the caller will see it.
When passing by value, the copy constructor will be called. The default copy constructor will only do a shallow copy, hence, if the called function modifies an integer in the object, this will not be seen by the calling function, but if the function changes a data structure pointed to by a pointer within the object, then this will be seen by the caller due to the shallow copy.
通过引用传递时,对同一对象的引用将传递给被调用的函数。对对象的任何更改都将反映在原始对象中,因此调用者将看到它。
按值传递时,将调用复制构造函数。默认的复制构造函数只会做一个浅拷贝,因此,如果被调用的函数修改了对象中的一个整数,调用函数不会看到,但是如果函数改变了对象内的指针指向的数据结构,那么由于浅拷贝,调用者将看到这一点。
I might have mis-understood your question, but I thought I would give it a stab anyway.
我可能误解了你的问题,但我想无论如何我都会试一试。
回答by dreeves
As I parse it, those words are wrong. It should read "If the function modifies that value, the modifications appear also within the scope of the calling function when passing by reference, but not when passing by value."
当我解析它时,这些词是错误的。它应该显示为“如果函数修改了该值,则在按引用传递时,修改也会出现在调用函数的范围内,但在按值传递时不会出现。”
回答by jwpfox
My understanding of the words "If the function modifies that value, the modifications appear also within the scope of the calling function for both passing by value and by reference" is that they are an error.
我对“如果函数修改了那个值,修改也出现在调用函数的范围内,通过值和引用传递”这句话的理解是它们是一个错误。
Modifications made in a called function are notin scope of the calling function when passing by value.
按值传递时,在被调用函数中所做的修改不在调用函数的范围内。
Either you have mistyped the quoted words or they have been extracted out of whatever context made what appears to be wrong, right.
要么你打错了引用的单词,要么它们是从任何看起来错误的上下文中提取出来的,正确的。
Could you please ensure you have correctly quoted your source and if there are no errors there give more of the text surrounding that statement in the source material.
请确保您正确引用了您的来源,如果没有错误,请在源材料中提供更多围绕该声明的文本。