Zwracanie i przekazywanie przez referencje

0

Nie daje mi spokoju jedna sprawa... Podobno funkcja może zwracać przez referencje, ale jeżeli funkcja zwraca przez referencje swoje zmienne lokalne jest to błąd, ponieważ referencja będzie wskazywała na nie istniejący obiekty co jest błędem. Więc rozumiem przez to, że funkcja może zwracać przez referencje tylko te obiekty które sama otrzymała przez referencje tak? np kod:

int &suma(int a,int b)
{
	int wynik=a+b;
	return wynik;
}
int main(){
int &rSuma=suma(5,7);

jest błędny tak?

gdybyśmy wynik zaalokowali na stercie też by nam to na wiele nie dało bo to skończeniu funkcji utracilibyśmy wskaźnik do tego obiektu i nie moglibyśmy zwolnić bezpośrednio pamięci kiedy nie będzie ona potrzebna, a nawet jeśli utworzylibyśmy nowy wskaźnik i przypisali adres rSuma poczym byśmy go zwolnili znow by powstał błąd gdyż rSuma znowu wskazywała by na nie istniejący obiekt;/

Czy jedynym rozwiązaniem tego problemu jest utworzenie zmiennej wynik w funkcji wywołującej i przekazanie jej do funkcji wywołanej referencyjnie a następnie zwrócić ją również referencyjnie? Czy istnieje jakaś możliwość aby funkcja zwracała referencyjnie obiekt który nie otrzymała referencyjnie i nie występowały przy tym żadne błędy typu:referencja do pustego obiektu lub wyciek pamięci przez utratę wskaźnika?

0

Podobno funkcja może zwracać przez referencje
Tak, to prawda.

jeżeli funkcja zwraca przez referencje swoje zmienne lokalne jest to błąd, ponieważ referencja będzie wskazywała na nie istniejący obiekt
Tak.

Więc rozumiem przez to, że funkcja może zwracać przez referencje tylko te obiekty które sama otrzymała przez referencje tak?
Nie, może też zwrócić referencję do obiektu dostępnego globalnie, a metoda może zwrócić referencję do pola, czy do *this (czyli instancji obiektu, na rzecz którego została wywołana).

np kod: [kod] jest błędny tak?
Tak.

gdybyśmy wynik zaalokowali na stercie...
Podaj ilustrujący to zachowanie kod, bo naprawdę ciężko mi wydedukować o co Ci w tym przypadku chodzi.

Czy jedynym rozwiązaniem tego problemu...
Jakiego problemu? Dlaczego chcesz tu koniecznie zwracać przez referencję? Przecież to nie ma większego sensu... Zwróć przez wartość, w końcu wynik jest nowym obiektem. ;)

0

int &suma(int a, int b)
{
int* w = new int;
*w = a+b;
return *w;
}

0

Jeżeli dobrze cię zrozumiałem, to jest to niemożliwe. Powiedzmy chcesz zwrócić przez referencję obiekt. Żeby nie "zajmował" miejsca na stosie (którego nie może zajmować po wyjściu z funkcji) należy umieścić go w innym miejscu pamięci, czyli albo malloc, albo zmienna globalna/statyczna. W pierwszym wypadku należy pamiętać o zwolnieniu pamięci (lub może zastosować jakiś auto_ptr itp.), a w drugim jesteś ograniczony tylko do jednego obiektu. Ogólnie jeżeli kopiowanie jest tanie, to bym zwracał przez wartość, w innym wypadku zwykle należy podać wskaźnik do obiektu jako parametr.

0

Mógłbyś zrobić to jak pokazał galleanv, ale to nie ma sensu praktycznego. Szukasz problemu dla jakiegoś rozwiązania czy rozwiązania dla problemu? Nie twórz na siłę sztucznych rozwiązań. Referencja to tylko pewien alias dla czegoś co istnieje i już ma zapewniony mechanizm zwolnienia przydzielonej pamięci (a w tym wywołania destruktora).

0

@Azrael_Valedhel wiem,że w tym kodzie mogę spokojnie zwracać wynik funkcji przez wartość, chciałbym jednak na przyszłość wiedzieć jak zwracać przez referencje bez błędów, a ten kod miał tylko ilustrować sytuację
co do sterty: program galleanv przedstawia tą sytuację. Wtedy referencja będzie się odwoływać do rzeczywistego obiektu i w tym programie nie jest to wielki błąd że utraciliśmy ten wskaźnik(pod warunkiem,że ten program nie ma nic więcej robić), ale może się nadarzyć sytuacja, że będę zmuszony zwolnić ten wskaźnik i wtedy będę mógł to zrobić pośrednio przez utworzenie nowego wskaźnika i zainicjalizowanie go adresem referencji a następnie zwolnienie nowo utworzonego wskaźnika ale wtedy znowu referencja będzie wskazywała na nie istniejący obiekt.

@Zjarek zdam się na to co napisałeś,że jest to niemożliwe bo zdaje mi się że mnie zrozumiałeś ;D
Mógłbym Was jeszcze prosić o to, abyście napisali mi w jakich sytuacjach najlepiej jest zwracanie przez referencję? Bo nie do końca widzę cel takiego zwracania...

0

Co do zwracania przez referencję, to pierwszy przykład który mi się nasuwa to łączenie operatorów w łańcuch, patrz iostream. Inaczej nie możliwe było by robienie czegoś takiego jak cin>>a>>b>>c; ( ((cin.operator>>(a)).operator>>(b)).operator>>(c); )Często zwraca się też wartości przez referencję w metodach klasy, ponieważ wtedy te wartości istnieją (najprostszy przykład - std::vector<T>::operator[] zwraca T&).

0

trochę odkopię, jestem na etapie nauki referencji i mam pytanie do kodu z pierwszego postu, wiem że on nie działa bo zwracana jest nieistniejąca wartość, moje pytanie jest następujące: dlaczego ta wartość nie istnieje już w pamięci ? przecież jak zwracam wartość normalnie, a nie przez referencję to program główny wie gdzie szukać tych danych i je widzi, a z jakiego powodu nie widzi takiej zmiennej ? Mam nadzieje że ktoś zrozumiał o co mi chodzi : D Z góry dziękuję za pomoc : )

1

dlaczego ta wartość nie istnieje już w pamięci ? przecież jak zwracam wartość normalnie, a nie przez referencję to program główny wie gdzie szukać tych danych i je widzi, a z jakiego powodu nie widzi takiej zmiennej ?

Zwracając przez wartość, kopiujesz tą wartość do miejsca wywołania funkcji i jest on zapisana pod adresem zmiennej, do której następuje przypisanie.
Natomiast zwrócając przez referencję, zwracamy adres zmiennej lokalnej w funkcji, która po zakończeniu działania sprząta po sobie i adres odnosi się do nieistniejącej (posprzątanej) zmiennej.

0

Dziękuję! Teraz wszystko jasne : )

1 użytkowników online, w tym zalogowanych: 0, gości: 1