C++ Return value, reference, const reference

Czy możesz mi wyjaśnić różnicę między zwracaniem wartości, odniesieniem do wartości i odniesieniem do const do wartości?

Wartość:

Vector2D operator += (const Vector2D& vector)
{
    this->x += vector.x;
    this->y += vector.y;
    return *this;
}

Not-const reference:

Vector2D& operator += (const Vector2D& vector)
{
    this->x += vector.x;
    this->y += vector.y;
    return *this;
}

Const reference:

const Vector2D& operator += (const Vector2D& vector)
{
    this->x += vector.x;
    this->y += vector.y;
    return *this;
}
Jaka jest z tego korzyść? Rozumiem sens przechodzenia referencji const do funkcji, ponieważ chcesz się upewnić, że nie modyfikujesz tej wartości, na którą Referencja wskazuje wewnątrz funkcji. Ale jestem zdezorientowany przez Znaczenie zwracam const reference. Dlaczego zwracanie referencji jest lepsze niż zwracanie wartości i dlaczego zwracanie referencji const jest lepsze niż zwracanie referencji not-const?
Author: ankit, 2014-02-14

5 answers

Nie ma różnicy, chyba że napiszesz coś dziwnego jak

(v1 += v2) = v3;

W pierwszym przypadku przypisanie będzie tymczasowe, a ogólny efekt będzie v1 += v2.

W drugim przypadku, przypisanie będzie v1, więc ogólny efekt będzie v1 = v3.

W trzecim przypadku, zadanie nie będzie dozwolone. Jest to prawdopodobnie najlepsza opcja, ponieważ taka dziwność jest prawie na pewno błędem.

Dlaczego zwracanie referencji jest lepsze niż zwracanie wartości?

Jest potencjalnie bardziej wydajny: nie musisz robić kopii obiektu.

I dlaczego zwracanie referencji const jest lepsze niż zwracanie referencji not-const?

Zapobiegasz dziwności, jak w powyższym przykładzie, jednocześnie pozwalając na mniej dziwne łańcuchy, takie jak

v1 = (v2 += v3);

Ale, jak zaznaczono w komentarzach, oznacza to, że Twój typ nie obsługuje tych samych form (ab), co typy wbudowane, które niektórzy ludzie Uznaj za pożądane.

 18
Author: Mike Seymour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 12:39:13

Wartość:

Zwracanie przez wartość oznacza, że zwracasz kopię obiektu. To stawia wymagania na klasę(musi być kopiowalna lub ruchoma). Oznacza to, że dla obiektu niektórych klas zwracanie wartości może być kosztowne(w przypadku, gdy RVO lub NRVO nie działa lub jest wyłączone). Oznacza to również, że nowy obiekt jest niezależny (w zależności od jego konstrukcji) od innych obiektów i stanowi własną wartość. To jest to, co prawdopodobnie należy zwrócić z wielu binarnych operatory takie jak+, -, * i tak dalej.

Non-const reference:

Naprawdę zwracasz alias dla innego obiektu. Alias jest non const pozwala na modyfikację aliased obiektu. To jest to, co powinieneś zwrócić z niektórych nieartykułowanych opratorów, takich jak prefix ++ i--, oraz * (dereference), ponieważ zwykle chcesz mieć możliwość modyfikowania zwracanego obiektu.

To jest zwracane przez operator > > i operator

cout << 5 << "is greater then" << 1 << endl;
cin >> myInt >> myFloat;

Możesz również zwrócić referencję do * this, jeśli chcesz zezwolić na łańcuchowanie zwykłych metod, takich jak:

object.run().printLastRunStatistics();

Const reference:

Jak wyżej, ale nie można modyfikować aliasowanego obiektu. Może być używany zamiast zwracania przez wartość, gdy zwracany obiekt jest drogi do skopiowania i kiedy można zapewnić jego istnienie po powrocie z funkcji.

To jest to, co operator = zwykle zwraca, aby umożliwić wiele przypisań w sposób standardowy typy je obsługują:

a = b = c;

Const-Referencja używana w operatorze = zapobiega tego typu użytkowaniu (nie wspierana przez Standardowy Typ o ile pamiętam):

++(a = b);

Co byłoby dozwolone, gdyby użyto normalnego odniesienia.

 6
Author: Tomek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 11:44:13

Jest to dokładnie to samo, co przekazanie argumentu do funkcji.

Chcesz zwrócić referencję const gdy zwracasz właściwość obiektu, którego nie chcesz modyfikować poza jego stroną. Na przykład: jeśli twój obiekt ma nazwę, możesz utworzyć następującą metodę const std::string& get_name(){ return name; };. Co jest najbardziej optymalnym sposobem. Zezwalasz na" tylko do odczytu " dostęp do wewnętrznej właściwości, z out copy-on-return.

Podczas przeciążania operatorów oczekuje się, że zwrócisz obiekt, który jest zmienny, w przeciwnym razie pewna składnia, która zwykle ma działać, spowoduje błędy. Jest to dość ważne, gdy próbujesz jakiegoś dziwnego łączenia.

Na przykład opcja 3 nie będzie działać z czymś takim jak (v1 += v2).non_const_method(), Podczas Gdy:

v1+=v2;
v1.non_const_method();
 5
Author: luk32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 11:36:07

Różnica między return-by-value i return-by-reference obowiązuje w czasie wykonywania:

Gdy zwracasz obiekt według wartości, wywoływany jest Konstruktor kopiujący, a na stosie tworzona jest tymczasowa instancja.

Po zwróceniu obiektu przez odniesienie, wszystkie powyższe nie mają miejsca, co prowadzi do poprawy wydajności.


Różnica między return-by-reference i return-by-constant-reference nie ma run-time effect, i jest po prostu tam, aby chronić Cię przed pisaniem błędnego kodu.

Na przykład za pomocą Vector2D& operator += (const Vector2D& vector) można wykonać:

(x+=y)++ lub (x+=y).func() Gdzie func jest funkcją non-const w klasie Vector2D.

Ale z const Vector2D& operator += (const Vector2D& vector), kompilator wygeneruje błąd dla każdej takiej podobnej próby.

 3
Author: barak manos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 11:36:11

Jak wspomniano ale luk32 jest to tylko po to, aby upewnić się, że żadne zmiany nie są dozwolone w obiektach zwracanych przez tę funkcję. Może to w zasadzie pomóc w znalezieniu błędów logicznych w czasie kompilacji. Załóżmy, że na pewno nie zmienisz obiektu, a Twój kod zmienia obiekt, można go śledzić. Można pomyśleć o dobrej praktyce kodowania.

 1
Author: 51k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 11:32:38