Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Po co zwracać referencje?

Ostatnio zmodyfikowano 2015-11-17 22:44
Autor Wiadomość
emSon
Temat założony przez niniejszego użytkownika
[C++] Po co zwracać referencje?
» 2015-11-16 16:36:50
Jaki jest sens zwracania referencji?

C/C++
free_throws & accumulate( free_throws & target, const free_throws & source );

Wiadomo, że wtedy nie można wywoływać funkcji w funkcji

C/C++
accumulate( accumulate( team, three ), four );

Ale czy jest inne zastosowanie tego? Jeśli nie używam zagnieżdżonych funkcji mój prototyp równie dobrze może wyglądać tak:

C/C++
free_throws accumulate( free_throws & target, const free_throws & source );
P-140216
Monika90
» 2015-11-16 17:05:18
Jaki jest sens zwracania referencji?

Zobacz np. operator [] klasy std::vector


Wiadomo, że wtedy nie można wywoływać funkcji w funkcji
C/C++
accumulate( accumulate( team, three ), four );

Można, zobacz operator wstawiania do strumienia << - zwraca referencję, a możliwe jest wywołanie łańcuchowe (to co ty nazywasz wywołaniem funkcji w funkcji)



równie dobrze może wyglądać tak:
C/C++
free_throws accumulate( free_throws & target, const free_throws & source );
Między zwracaniem referencji, a wartości jest duża różnica. Czy w tym przypadku można zastąpić jedno drugim - nie wiem, bo nie wiem co ta funkcja ma robić.
P-140217
emSon
Temat założony przez niniejszego użytkownika
» 2015-11-16 17:17:17
O tym operatorze się jeszcze nie uczyłem.
Funkcja ta zwraca podesłaną przez referencję strukture:

C/C++
free_throws & accumulate( free_throws & target, const free_throws & source )
{
    target.attempts += source.attempts;
    target.made += source.made;
    return target;
}

Czy w tym wypadku jest jakaś różnica?
P-140218
Monika90
» 2015-11-16 17:28:07
Jeżeli będziesz zwracał przez wartość, to nie będziesz mógł wywołać tej funkcji w ten sposób
C/C++
accumulate( accumulate( team, three ), four );
ponieważ ta funkcja jako pierwszego argumentu wymaga L-wartości, a obiekt zwracany z funkcji przez wartość jest R-wartością. Dlatego tutaj musisz zwracać referencję. Inny powód zwracania referencji to to że prawdopodobnie chcesz uniknąć zbędnych kopii obiektu team. (ale nie zwracaj referencji do obiektów lokalnych - to byłby błąd)

UWAGA, jeżeli używasz kompilatora Microsoftu, to powyższe wywołanie się skompiluję nawet jeżeli nie zwracasz przez referencję, ale takie zachowanie kompilatora nie jest zgodne ze standardem.
P-140220
emSon
Temat założony przez niniejszego użytkownika
» 2015-11-16 17:32:29
Ok, już rozumiem. Dzięki ci wielkie ;)
P-140221
j23
» 2015-11-16 17:44:22
UWAGA, jeżeli używasz kompilatora Microsoftu, to powyższe wywołanie się skompiluję nawet jeżeli nie zwracasz przez referencję, ale takie zachowanie kompilatora nie jest zgodne ze standardem.
VC++ EE 2012:
Kompilator:
cannot convert parameter 1 from 'free_throws' to 'free_throws &'

Intellisense:
initial value of reference to non-const must be an lvalue
P-140222
Monika90
» 2015-11-16 21:16:52
Ich najnowszy (chyba) kompilator 19.00.23427.0(x86) Update 1 RC, produkuje tylko ostrzeżenie


Compiled with  /EHsc /nologo /W4 /c
main.cpp
main.cpp(8): warning C4239: nonstandard extension used: 'argument': conversion from 'X' to 'X &'
main.cpp(8): note: A non-const reference may only be bound to an lvalue

Compilation successful!

Formalnie takie zachowanie jest zgodne ze standardem, w poście wyżej chodziło mi o to, że program który z tego rozszerzenia korzysta nie jest napisany w standardowym C++.
P-140236
j23
» 2015-11-17 10:56:48
Sprawdziłem na nowszej wersji środowiska - VS Community 2013 (kompilator 18.00.31101). Wyszły te same błędy co w VS 2012 EE. Nie chce mi się wierzyć, żeby w następnej wersji kompilatora o tak zmienili podejście do tego typu konstrukcji. Jeśli kompilujesz w innym IDE, dodaj opcję /Za.
P-140272
« 1 » 2
  Strona 1 z 2 Następna strona