简体   繁体   English

关于通过引用传递的怀疑

[英]Doubts about passing by reference

i'm studying C++ and, in particular,i have stopped on references. 我正在学习C ++,特别是我已停止参考。 I apologize if my question will be trivial to most of you,but i would like to understand the output of this program: 如果我的问题对你们大多数人来说都是微不足道的,我很抱歉,但我想了解这个程序的输出:

#include <iostream>

using namespace std;

struct myStruct
{
    int a;
    int b;
};
typedef struct myStruct myStruct;

myStruct copyMyStruct(myStruct& source)
{
    myStruct dest;
    dest.a=source.a;
    dest.b=source.b;
    return dest;
}

myStruct otherCopyMyStruct(myStruct& source)
{
    myStruct dest;
    dest=source;
    return dest;
}

myStruct& GetRef(myStruct& source)
{
    return source;
}

void printMyStruct(string name,const myStruct& str)
{
    cout<<name<<".a:"<<str.a<<endl;
    cout<<name<<".b:"<<str.b<<endl;
}

myStruct one,two,three,four;
myStruct& five=one;

void printStructs()
{
    printMyStruct("one",one);
    printMyStruct("two",two);
    printMyStruct("three",three);
    printMyStruct("four",four);
    printMyStruct("five",five);
}

int main()
{
    one.a=100;
    one.b=200;

    two=copyMyStruct(one);
    three=otherCopyMyStruct(one);
    four=GetRef(one);


    printStructs();

    cout<<endl<<"NOW MODIFYING one"<<endl;

    one.a=12345;
    one.b=67890;

    printStructs();

    cout<<endl<<"NOW MODIFYING two"<<endl;

    two.a=2222;
    two.b=2222;

    printStructs();

    cout<<endl<<"NOW MODIFYING three"<<endl;

    three.a=3333;
    three.b=3333;

    printStructs();

    cout<<endl<<"NOW MODIFYING four"<<endl;

    four.a=4444;
    four.b=4444;

    printStructs();


    cout<<endl<<"NOW MODIFYING five"<<endl;

    five.a=5555;
    five.b=5555;

    printStructs();

    return 0;
}

The output is: 输出是:

one.a:100
one.b:200
two.a:100
two.b:200
three.a:100
three.b:200
four.a:100
four.b:200
five.a:100
five.b:200

NOW MODIFYING one
one.a:12345
one.b:67890
two.a:100
two.b:200
three.a:100
three.b:200
four.a:100
four.b:200
five.a:12345
five.b:67890

NOW MODIFYING two
one.a:12345
one.b:67890
two.a:2222
two.b:2222
three.a:100
three.b:200
four.a:100
four.b:200
five.a:12345
five.b:67890

NOW MODIFYING three
one.a:12345
one.b:67890
two.a:2222
two.b:2222
three.a:3333
three.b:3333
four.a:100
four.b:200
five.a:12345
five.b:67890

NOW MODIFYING four
one.a:12345
one.b:67890
two.a:2222
two.b:2222
three.a:3333
three.b:3333
four.a:4444
four.b:4444
five.a:12345
five.b:67890

NOW MODIFYING five
one.a:5555
one.b:5555
two.a:2222
two.b:2222
three.a:3333
three.b:3333
four.a:4444
four.b:4444
five.a:5555
five.b:5555

My question: why don't the changes on "two","three" and "four" produce a change on "one"? 我的问题:为什么“两个”,“三个”和“四个”的变化不会对“一个”产生变化?

I can guess what happens to "two" and "three": probably a member by member copy to a newly created variable, but i don't understand why the change on "four" isn't reflected on "one" (and "five"): after all i return a reference from the GetRef function .... 我可以猜到“两个”和“三个”会发生什么:可能是成员复制到新创建的变量的成员,但我不明白为什么“四”的变化没有反映在“一”(和“五“):毕竟我从GetRef函数返回一个引用....

Thanks in advance! 提前致谢!

The variable four is an object, not a reference. 变量four是一个对象,而不是一个引用。

When you assign to it from a reference, four=GetRef(one); 从引用分配给它时, four=GetRef(one); , four doesn't turn into a reference. four不会变成参考。 The assignment copies whatever is referred to by the reference (in this case, that referand is one ). 赋值复制引用引用的任何内容(在这种情况下,引用是one )。 After that, the objects are unrelated. 之后,对象是不相关的。 So four = GetRef(one); 所以four = GetRef(one); has the same effect as four = one; 效果与four = one;相同four = one; .

myStruct &five = one; , on the other hand, declares five as a reference (not an object), and "binds" the object one to the reference. ,另一方面,声明five为基准(不是对象),和“结合”的对象one到参考。 So the name five and the name one refer to the same object, meaning that of course changes made using either name can be seen using the other name. 因此,名称为five ,名称one指向同一对象,这意味着当然可以使用其他名称查看使用任一名称所做的更改。

By the way, there's no need[*] for typedef struct myStruct myStruct; 顺便说一句, typedef struct myStruct myStruct;不需要[*] typedef struct myStruct myStruct; in C++. 在C ++中。 In C++, a class type can just be referred to by name, and structs are classes. 在C ++中,类类型只能通过名称引用,而结构类型类。

[*] except for a somewhat weird corner case where you have a function with the same name as a class, whose parameters are compatible with the parameters of some constructor of that class. [*]除了一个有点奇怪的角落情况,你有一个与类同名的函数,其参数与该类的某些构造函数的参数兼容。 Then you might think the expression Foo(x,y) would be ambiguous between the function Foo and the constructor call on Foo . 然后,你可能会想表达Foo(x,y)将是功能之间的暧昧Foo和构造函数调用Foo But no - in the absence of a typedef, C of course chooses the function, and so for compatibility with C, C++ does the same thing. 但是没有 - 在没有typedef的情况下,C当然会选择函数,因此为了与C兼容,C ++也做同样的事情。 Most people don't find this case compelling enough to write the typedefs in C++. 大多数人都认为这种情况不足以在C ++中编写typedef。

Because copymystruct returns 'by value'. 因为copymystruct按值返回。 It involves creating a seperate temporary object which is returned by value and assigned to the result which is a separate object. 它涉及创建一个单独的临时对象,该对象由value返回并分配给结果,该结果是一个单独的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM