2010-11-20 69 views
2

我正在学习C++,特别是我停止参考。我很抱歉,如果我的问题将是微不足道的绝大多数人,但我想了解该程序的输出:关于通过引用的疑问

#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; 
} 

输出是:

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 

我的问题:为什么不“二”,“三”和“四”的变化会对“一”产生变化吗?

我可以猜到“two”和“three”会发生什么:可能是成员通过成员复制到新创建的变量,但我不明白为什么“four”上的更改没有反映在“one “(和”五“):毕竟我从GetRef函数返回一个参考....

在此先感谢!

+0

GetRef返回相同的内容,但当分配给'four'时会发生什么?这不是一个参考... – 2010-11-20 01:11:46

回答

8

变量four是一个对象,而不是一个引用。

当您从参考中分配给它时,four=GetRef(one);,four不会变成参考。该作业复制参考文献提及的任何内容(在这种情况下,该参考文献是one)。之后,这些对象是不相关的。因此four = GetRef(one);four = one;具有相同的效果。

myStruct &five = one;另一方面声明five作为参考(而不是对象),并且将对象one“绑定”到参考。所以名称five和名称one指的是同一个对象,这意味着当然可以使用其他名称查看使用任一名称进行的更改。

顺便说一句,在C++中不需要[*] typedef struct myStruct myStruct;。在C++中,一个类的类型可以用名字来引用,而结构体类。

[*]除了有点奇怪的角落情况下,你有一个与一个类同名的函数,其参数与该类的某个构造函数的参数兼容。那么你可能会认为表达式Foo(x,y)在函数FooFoo上的构造函数调用之间可能不明确。但是没有 - 在没有typedef的情况下,C当然选择了函数,因此为了与C兼容,C++执行相同的操作。大多数人没有发现这种情况足以使用C++编写typedefs。

+0

更详细地说,人们会说'四个= GetRef(one)'调用赋值运算符'myStruct :: operator =(myStruct&copyfromthis)'。如果您没有定义赋值运算符,那么编译器会创建一个默认情况下执行逐个成员拷贝的运算符。 – Crashworks 2010-11-20 01:16:07

+0

是的。在这种情况下,赋值如上所述复制对象,但对于重载'operator ='的类,赋值会执行重载定义它执行的操作。 – 2010-11-20 01:17:27

0

因为copymystruct返回'按值'。它涉及到创建一个单独的临时对象,该对象通过值返回并分配给作为单独对象的结果。