Pass by Reference / Value in C++
我想通过价值和参考来澄清两者之间的差异。
我画了一幅画
。
所以,为了传递价值,
使用不同的引用创建相同对象的副本,并为局部变量分配新引用,以便指向新副本。
如何理解单词:他说:"这是一个很好的选择。"如果函数修改了该值,修改也会出现在通过值和引用传递的调用函数范围内他说:"这是一个很好的选择。"
谢谢!
我认为很多混淆是由于没有传达引用传递的含义而产生的。当一些人说通过引用时,他们通常不是指参数本身,而是指被引用的对象。另一些人说,通过引用意味着不能在被调用方中更改对象。例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 } |
有些人会声称1和3是通过引用传递的,而2是通过值传递的。另一组人说,除了最后一组以外,其余的都是通过引用传递的,因为对象本身没有被复制。
我想在这里画一个定义,我声称通过参考。关于它的一个一般性的概述可以在这里找到:传递引用和传递值之间的区别。第一个和最后一个是传递值,中间两个是传递引用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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. |
我投票赞成以下定义:
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 and the reference parameter binds directly to the argument expression (8.5.3/4). In all other cases, we have to do with pass by value.
这意味着以下是传递值:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 2 3 4 5 6 7 8 9 10 | 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 |
传递值时:
1 | void func(Object o); |
然后打电话
1 | func(a); |
您将在堆栈上构造一个
通过引用传递时:
1 | void func2(Object& o); |
然后打电话
1 | func2(a); |
你只会提供一种新的方式来参考
非常感谢所有人提供这些意见!
我在网上的一篇演讲稿中引用了这句话:http://www.cs.cornell.edu/courses/cs213/2002fa/chassors/stearce02/stearce02.pdf
第一页第六张幻灯片
"通过值变量的值被传递给函数如果函数修改了该值,则修改将保留在职能范围。
通过引用对变量的引用将传递给函数如果函数修改了该值,修改也会出现在调用函数的范围内。
"
再次感谢!
我不确定我是否正确理解你的问题。有点不清楚。但是,您可能会困惑的是:
当通过引用传递时,对同一对象的引用将传递给被调用的函数。对对象的任何更改都将反映在原始对象中,因此调用方将看到它。
传递值时,将调用复制构造函数。默认的复制构造函数只做一个浅复制,因此,如果被调用的函数修改了对象中的整数,调用函数将看不到这一点,但是如果函数更改了对象中指针指向的数据结构,那么调用方将看到这一点,因为是浅复制。
我可能误解了你的问题,但我想我还是要试一试。
当我分析它时,那些词是错误的。它应该是这样的:"如果函数修改了该值,那么当通过引用传递时,修改也出现在调用函数的范围内,而不是通过值传递时。"
我对"如果函数修改了该值,那么修改也出现在调用函数的范围内,以便传递值和引用",这是一个错误。
传递值时,在被调用函数中所做的修改不在调用函数的范围内。
要么你错打了引用的单词,要么它们是从任何上下文中提取出来的,这让你觉得是错的,对的。
请确保您正确引用了源代码,如果没有错误,请在源代码材料中提供更多关于该语句的文本。