当前位置:  开发笔记 > 编程语言 > 正文

在C++中通过引用/值传递

如何解决《在C++中通过引用/值传递》经验,为你挑选了4个好方法。

我想澄清价值和参考之间的差异.

我画了一张照片

在此输入图像描述

所以,为了通过价值,

使用不同的引用创建相同对象的副本,并为本地变量分配新引用,以指向新副本

如何理解单词:"如果函数修改了该值,则修改也出现在调用函数的范围内,用于传递值和引用"

谢谢!



1> Johannes Sch..:

我认为通过不传达通过引用传递的含义会产生很多混淆.当有人说通过引用传递它们通常意味着不是参数本身,而是被引用的对象.其他一些人说通过引用传递意味着无法在被调用者中更改对象.例:

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会通过值传递.另一组人说除了最后一个都是通过引用传递,因为对象本身没有被复制.

我想在这里描述一下我声称通过引用传递的内容.可以在此处找到对它的一般概述:传递参考和传递值之间的差异.第一个和最后一个是按值传递,中间两个是按引用传递:

    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.

我投票支持以下定义:

当且仅当被调用函数的相应参数具有引用类型引用参数直接绑定到参数表达式(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是按值传递,因为参数没有引用类型.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



2> Flame..:

通过值时:

void func(Object o);

然后打电话

func(a);

你将Object在堆栈上构造一个,并在func它的实现中引用o.这可能仍然是一个浅的副本(内部ao可能指向相同的数据),因此a可能会更改.但是如果o是深层副本a,那么a就不会改变.

通过参考时:

void func2(Object& o);

然后打电话

func2(a);

你只会提供一种新的参考方式a." a"和" o"是同一对象的两个名称.更改o内部func2将使调用者可以看到这些更改,调用者通过名称" a" 知道对象.



3> user36064..:

非常感谢所有这些人的投入!

我从在线讲义中引用了这句话:http: //www.cs.cornell.edu/courses/cs213/2002fa/lectures/Lecture02/Lecture02.pdf

第6页幻灯片的第一页

"传递VALUE变量的值传递给函数如果函数修改了该值,则修改将保持在该函数的范围内.

通过参考传递对变量的引用传递给函数如果函数修改了该值,则修改也出现在调用函数的范围内.

"

再次感谢!



4> 小智..:

我不确定我是否正确理解你的问题.有点不清楚.但是,令您困惑的是以下内容:

    通过引用传递时,对同一对象的引用将传递给被调用的函数.对象的任何更改都将反映在原始对象中,因此调用者将看到它.

    传递值时,将调用复制构造函数.默认的复制构造函数只会执行浅拷贝,因此,如果被调用的函数修改了对象中的整数,调用函数就不会看到它,但是如果函数改变了对象内指针指向的数据结构,然后由于浅拷贝,调用者将看到这一点.

我可能误解了你的问题,但我还是认为无论如何我会试一试.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有