c++ - C++中按引用和值传递

标签 c++ pass-by-reference pass-by-value

我想澄清按值和按引用之间的区别。

我画了一张图:

Enter image description here

因此,对于按值传递,使用不同的引用创建相同对象的拷贝,并为局部变量分配新引用,从而指向新拷贝

我应该如何理解以下内容?

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

最佳答案

我认为没有传达通过引用传递 的含义会产生很多困惑。当一些人说通过引用传递时,他们通常不是指参数本身,而是被引用的对象。其他人说通过引用传递意味着不能在被调用者中更改对象。示例:

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 是按值传递。另一群人说除了最后一个以外的所有都是通过引用传递的,因为对象本身没有被复制。

我想在这里给出一个定义,我声称是通过引用传递。可以在这里找到它的一般概述:Difference between pass by reference and pass by value .第一个和最后一个是按值传递,中间两个是按引用传递:

    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.

这意味着以下是按值传递:

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 是按值传递的,因为它不是直接绑定(bind)的。实现可能会复制临时文件,然后将该临时文件绑定(bind)到引用。 2 是按值传递的,因为实现初始化了文字的临时值,然后绑定(bind)到引用。 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

关于c++ - C++中按引用和值传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23697035/

相关文章:

r - 使用 r 中的常见随机数进行采样(高效!)

c++ - 为什么string_view::operator ==按值接受参数

带有引用参数的 C# Web 服务

javascript - 如何在javascript中复制引用的值?

C++ 类变量不保留值

c++ - 从构造函数间接调用纯虚函数是否总是未定义的行为?

c++ - 通过引用 vector 给出错误的结果

javascript强制更新输入框上的ng-model值

c++ - decltype(auto) 类型推导 : return x vs. return (x)

c++ - 无法创建 QFile(仅适用于 msvc2017 uwp)