在C ++中通过引用/值传递
我想澄清按价值和借鉴的差异。
我画了一张照片
所以,为了传递价值,
使用不同的引用创build相同对象的副本,并且将局部variables分配给新引用,以便指向新副本
如何理解这些词:“如果函数修改了这个值,那么这些修改也出现在调用函数的范围内,以便通过值传递和引用”
谢谢!
我觉得很多混淆是由于没有通过引用而传达的 。 当有些人说参考时,他们通常不是指自己,而是指被引用的对象 。 另外一些人说,通过引用意味着对象不能在被调用者中被改变。 例:
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是通过价值。 另外一群人说除了最后一个都是经过引用,因为对象本身没有被复制。
我想在这里画一个定义,我声称是通过引用 。 在这里可以find关于它的一般概述: 通过引用和按值传递之间的区别 。 除了第一个和最后一个都是通过引用:
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.
我投赞成以下定义:
当且仅当被调用的函数的相应参数具有引用types并且引用参数直接绑定到参数expression式(8.5.3 / 4)时,参数(1.3.1)才被引用传递。 在所有其他情况下,我们必须处理好传递价值。
这意味着以下是传递价值:
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
是通过值,因为参数没有引用types。 4
是由于同样的原因传递值。 5
是由于参数没有引用types而传递的值。 以下情况通过参考(按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
按价值传递时:
void func(Object o);
然后打电话
func(a);
你将在栈上构造一个对象,并将被o引用。 这可能仍然是一个浅的副本(a和o的内部可能指向相同的数据),所以可能会改变。 然而,o是a的深层副本,那么a不会改变。
通过引用传递时:
void func(Object& o);
然后打电话
func(a);
你只会给一个新的方法来引用一个。 a和o是同一个对象的名字。 更改里面的func将使这些变化对于知道该对象为a的调用者可见。
我不确定是否正确理解你的问题。 这有点不清楚。 但是,您可能会困惑的是以下几点:
-
当通过引用传递时,对同一个对象的引用被传递给被调用的函数。 对象的任何更改都会反映到原始对象中,因此调用者将看到它。
-
当传值时,复制构造函数将被调用。 默认的拷贝构造函数只会做一个浅拷贝,因此,如果被调用的函数修改了对象中的一个整数,调用函数就不会看到这个函数,但是如果这个函数改变了一个指针指向的数据结构,那么由于浅拷贝,调用者可以看到这一点。
我可能错误地理解了你的问题,但是我还是认为我会刺伤它。
非常感谢所有这些投入!
我在网上从一篇讲义引用了这句话: http : //www.cs.cornell.edu/courses/cs213/2002fa/lectures/Lecture02/Lecture02.pdf
第6页的第一页
“按值传递variables的值被传递给函数如果函数修改了该值,那么这些修改将保留在该函数的范围内。
通过引用传递variables的引用传递给函数如果函数修改了该值,则修改也会出现在调用函数的范围内。
“
再次感谢!
当我parsing它时,这些话是错误的。 它应该是:“如果函数修改了这个值,那么当通过引用传递时,这些修改也出现在调用函数的范围内,而不是在通过值传递时”。
我对“如果函数修改了这个值,这些修改也出现在调用函数的范围内,对于传递值和引用”的理解是它们是错误的 。
在调用函数中进行的修改不在调用函数的作用域中。
要么你错误地input了所引用的词语,要么就是从任何可能出现错误的语境中提取出来的,正确的。
你能否确保你已经正确地引用了你的来源,如果没有错误,那么在原始资料中给出更多与该陈述有关的文字。