Сомнения в прохождении по ссылке - PullRequest
2 голосов
/ 20 ноября 2010

Я изучаю 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

Мой вопрос:почему изменения «два», «три» и «четыре» не приводят к изменению «один»?

Я могу догадаться, что происходит с «двумя» и «тремя»: вероятно, членКопирование члена во вновь созданную переменную, но я не понимаю, почему изменение «четыре» не отражается на «один» (и «пять»): в конце концов я возвращаю ссылку из функции GetRef ....

Заранее спасибо!

Ответы [ 2 ]

8 голосов
/ 20 ноября 2010

Переменная four является объектом, а не ссылкой.

Когда вы присваиваете ему ссылку, four=GetRef(one);, four не превращается в ссылку.Присвоение копирует все, на что ссылается ссылка (в данном случае это ссылка one).После этого объекты не связаны.Таким образом, four = GetRef(one); имеет тот же эффект, что и four = one;.

myStruct &five = one;, с другой стороны, объявляет five как ссылку (не объект) и «связывает» объект oneк ссылке.Таким образом, имя five и имя one относятся к одному и тому же объекту. Это означает, что, конечно, изменения, сделанные с использованием любого имени, можно увидеть с использованием другого имени.

Кстати, в этом нет необходимости [*] для typedef struct myStruct myStruct; в C ++.В C ++ к типу класса можно обращаться по имени, а структуры являются классами.

[*], за исключением несколько странного углового случая, когда у вас есть функция с тем же именемкак класс, параметры которого совместимы с параметрами некоторого конструктора этого класса.Тогда вы можете подумать, что выражение Foo(x,y) будет неоднозначным между функцией Foo и вызовом конструктора Foo.Но нет - в отсутствие typedef, C, конечно, выбирает функцию, и поэтому для совместимости с C, C ++ делает то же самое.Большинство людей не находят этот случай достаточно убедительным, чтобы написать typedefs на C ++.

0 голосов
/ 20 ноября 2010

Потому что copymystruct возвращает «по значению». Он включает создание отдельного временного объекта, который возвращается по значению и присваивается результату, который является отдельным объектом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...