4 funkcje, która jest poprawna

0

Mam problem, takie zadanko mam: Które z poniższych funkcji są prawidłowe, a które błędne (wyjaśnić przyczynę błędu)?

int& funA(int &a, int &b) { if(a<b) return a; else return b; }
 int funB(int &a, int &b) { if(a<b) return a; else return b; }
 int funC(int a, int b)   { if(a<b) return a; else return b; }
int& funB(int a, int b)  { if(a<b) return a; else return b; }

Mógłby ktoś wyjaśnić? :)

0

Spróbuj skompilować i będziesz wiedział.

4

int& funB(int a, int b) { if(a<b) return a; else return b; } Nie można zwracać referencji na obiekt tymczasowy.

0

@Shalom, akurat się kompilują. ;P

@Proxima, czyli to co zwraca referencję jest błędne, tak? I tylko to jest błędne?

2

@Neeus nie mówie że sie nie skompilują. Ale sensowny kompilator podpowie ci, za pomocą warninga, że np. zwracanie referencji do lokalnej zmiennej to zły pomysł.

1

Każda jest prawidłowa, ale te zwracające int& mogą (nie muszą) być nieprawidłowo użyte, jeśli parametr przekazany funkcji zostanie zniszczony po wyjściu z funkcji.
Dlatego lepiej nie zwracać referencji, jeśli nie wie się, co się robi.

Najlepsza jest wersja C. Referencje nie są w tym przypadku w ogóle potrzebne ani wskazane.

EDIT: Wersja ostatnia jest zła, bo zwraca referencję do zmiennej lokalnej.

1
int & c(int & a, int & b)
{
    if (a>b)
    {
        return a;
    }
    else
    {
        return b;
    }
}

int a=5;
int b=10;
c(a,b)=4;
c(a,b)=13;
cout << a << " | " << b << endl;
 

to co pokaże się w konsoli to 13 | 4 :) jednak działa, nawet nie wiedziałem, że tak się da

2
int& funA(int &a, int &b) { if(a<b) return a; else return b; }

Poprawne ale wyjątkowo głupie.

int funB(int &a, int &b) { if(a<b) return a; else return b; }

Poprawne ale nadal głupie.

int funC(int a, int b) { if(a<b) return a; else return b; }

Poprawne i bez głupot.

int& funB(int a, int b)  { if(a<b) return a; else return b; }

UB

Na boku warto dodać, że zwracany przez return obiekt lokalny z funkcji nadal można złapać przez "referencję" (const l-value ref/r-value ref) ale ten przypadek jest wyjątkiem paragrafu 12.5. Oznacza to, że nie powoduje to wydłużenia czasu życia zwracanego obiektu do czasu życia referencji, jak ma to miejsce w innych przypadkach:

The second context is when a reference is bound to a temporary.118 The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
(...)
— The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.

0

wszystkie funkcje są poprawne, ale funkcje:

int funB(int &a,int &b) {if(a<b) return a; else return b;}
int& funD(int a int b)  {if(a<b) return a; else return b;} 

tak w sumie robią to samo co funkcja:

int funC(int a,int b)   {if(a<b) return a; else return b;} 
0

@Niikelion
Nie prawda.
Funkcja int& funD(int a int b) {if(a<b) return a; else return b;} wcale nie robi tego co funC.
To działa tylko i wyłącznie z tego powodu że obszar pamięci na który wskazuje referencja zwracana w funD jest JESCZE nie zmieniony (w twoim przykładzie u góry), ale zmiana wartości pod tym adresem to prawdopodobnie tylko kwestia czasu i farta/braku farta.

0

@Proxima
Jak nie prawda? funC zwraca tymczasowy int a funD referencję na tymczasowy int. A więc robią ogólnie to samo. Jeden i drugi int znika. Zwracają ten sam wynik. Błąd może być jedynie w wykorzystaniu takiej funkcji

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