2016-07-03 10 views
1

Ich lerne gerade C++ und bin etwas verwirrt über das Konzept, eine Referenz von einer Methode zurückzugeben. Betrachten Sie das folgende Spielzeug Beispiel:Einen Verweis auf eine Kopie aus einer C++ - Methode zurückgeben

#include <iostream> 
#include <vector> 

class IntHolder { 

private: 

    std::vector<int> d_values; 

public: 

    IntHolder() { 
     d_values.push_back(1); 
     d_values.push_back(2); 
     d_values.push_back(3); 
    } 

    std::vector<int> &values() { 
     return d_values; 
    } 

}; 

int main(int argc, char **argv) { 
    IntHolder h; 
    std::vector<int> ret_val = h.values(); 
    std::cout << ret_val.size() << std::endl; 

    ret_val.push_back(4); 
    ret_val.push_back(5); 

    std::cout << h.values().size() << std::endl; 

    return 0; 
} 

Dies druckt die folgenden auf die Standardausgabe:

3 
3 

Da wir einen Verweis auf d_values zurückkehren, sollte nicht das Objekt zurückgegeben die gleichen sein, die gespeichert wird in der Instanz von IntHolder, und damit wieder beim Aufruf h.values(), sollten wir eine Größe von 5 sehen?

Da dies nicht der Fall ist, was ist der Unterschied zwischen Rückgabe einen Verweis auf ein Objekt oder eine Kopie des Objekts? Gibt es einen Unterschied, wenn Sie von einer Methode zurückkehren?

Antwort

1

Ihre Methode gibt eine Referenz zurück, aber Sie weisen das Ergebnis dann einem anderen Vektor zu und verursachen eine Kopie. Um dies zu beheben, ändern Sie Ihre ret_val Definition:

std::vector<int> & ret_val = h.values(); 
+0

Oder einfacher, 'auto & ret_val' ... –

3

Sie sind Rückkehr eine Referenz aus der values Funktion, aber Sie sind nicht zuweisen, Objekt zu einer Referenzgröße zurückgegeben. Stattdessen machen Sie eine Kopie davon, weil Sie es einem neuen std::vector<int> namens ret_val zuweisen.

Sie wollen Ihren Code wie so modifizieren, um den zurück Bezug zu erfassen:

std::vector<int>& ret_val = h.values(); 

Oder vielleicht einfach:

auto& ret_val = h.values(); 
0

Wenn Sie einen Verweis zurückgeben, können Sie das gleiche Objekt zurück und Sie erstellen keine Kopie. Grundsätzlich scheint es, dass es ist, wie Sie es nicht erwarten:

std::cout << h.values().size() << std::endl; 
h.values().push_back(4); 
h.values().push_back(5); 
std::cout << h.values().size() << std::endl; 

zurückkehren würde

3 
5 

Die misstage ein anderer ist. Schauen wir uns an

std::vector<int> ret_val = h.values(); 

Sie entdeckt, dass ret_val eine Kopie h.d_values ist während h.values() ist eine Referenz darauf zurück. Wir könnten Sie den Code oben wie folgt umschreiben:

std::vector<int> &ret_ref = h.values(); // object returned by `h.values()` 
std::vector<int> ret_val = ret_ref; 

Wenn Sie ret_ref.push_back(4) anrufen, h.d_values ändern würde. Aber ret_val ist eine Kopie des zurückgegebenen Objekts und hat keinen Einfluss auf h.d_values.