在C ++中传递参考/值 [英] Pass by Reference / Value in C++

查看:120
本文介绍了在C ++中传递参考/值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我画了一张图片





按值,



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

如何理解这些单词:

如果函数修改该值,修改也会出现在调用函数范围内的

解决方案

div>

我认为很多混乱是由于不传达通过引用传递的意思。。当某些人说通过引用传递时,它们通常意味着不是参数本身,而是被引用的对象。一些其他说通过引用传递意味着对象不能在被调用者中更改。示例:

  struct Object {
int i;
};

void sample(Object * o){// 1
o-> i ++;
}

void sample(Object const& o){// 2
//这里没有用处:)
}

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); //调用1
sample(obj)//调用3
sample(obj_c); // calls 2
sample1(obj); // calls 4
}

有些人会声称1和3通过引用传递,而2将通过值。另一组人说除了最后一个是通过引用,因为对象本身没有复制。



我想在这里定义一个我声称通过引用传递的定义。您可以在此处查看对此的一般概述:通过引用传递和传递值之间的差异。除第一个和最后一个之外的所有内容都通过引用传递:

  sample(& obj); 
//产生一个Object *。通过值将*指针*传递给对象。
//调用者可以改变指针(参数),但
//不会改变在调用端创建的临时指针(参数)。

sample(obj)
//将对象传递给* reference *。它表示对象本身。被调用者
//具有参考参数。

sample(obj_c);
//也通过*引用*。引用参数引用
//与参数表达式相同的对象。

sample1(obj);
//传递值。参数对象表示与传递的
//不同的对象。

对于以下定义:


参数(1.3.1)通过引用传递,当且仅当函数的相应参数被调用具有引用类型,引用参数直接绑定到参数表达式(8.5.3 / 4)。在所有其他情况下,我们必须通过值传递。


这意味着以下是值传递:

  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 & 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); //传递静态的a通过引用


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!

解决方案

I think much confusion is generated by not communicating what is meant by passed by reference. When some people say pass by reference they 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.

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 . All but the first and last 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 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.

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):

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

这篇关于在C ++中传递参考/值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆