2010-11-20 73 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返回'按值'。它涉及到創建一個單獨的臨時對象,該對象通過值返回並分配給作爲單獨對象的結果。