2012-04-08 11 views
1

Verzeihen Sie mir, wenn das schon einmal gefragt wurde, ich bin sicher, dass es hat, aber ich konnte keine Antwort finden, mit der ich glücklich war.Zurückgeben von Zeichenfolgen durch Referenz cpp

Ich komme zu cpp von einem schweren Java-Hintergrund und möchte verstehen, wenn einen Verweis/Zeiger auf ein Objekt anstelle einer Kopie zurückgeben.

für die folgende Klassendefinition:

class SpaceShip { 
    string name; 
    WeaponSystem weaponSystem; //represents some object, this is just an example, I dont have this type of object at all in my program 
    int hull; 

    string GetName() const { 
     return name; 
    } 

    WeaponSystem GetWeaponSystem() const { 
     return weaponSystem; 
    } 

    int GetHull() const { 
     return hull; 
    } 
}; 

Ich weiß, dass eine Kopie der Dinge Rückkehr teuer ist, würde ich denke, das bedeutet, dass ich so etwas wie eine Schnur oder weaponSystem von Wert vermeiden will zurückkehren, sondern ein int nach Wert ist ok.

Ist das richtig? Ich weiß auch, dass ich mir bewusst sein muss, wo Dinge in Erinnerung bleiben, bedeutet die Rückkehr zu etwas in dieser Klasse Gefahr auf der ganzen Linie, wenn dieses Objekt zerstört wird und etwas noch einen Verweis auf seinen Namen besitzt?

+0

im Allgemeinen; Solange Sie kein * new * (Zuweisung eines Speicherorts auf dem Heap) verwenden, müssen Sie sich keine Gedanken über Speicherlecks machen. – Rps

+0

Während Sie Referenzen hier zurückgeben könnten, würde dies die Kapselung verletzen und zu undefiniertem Verhalten führen. Angenommen, Sie geben einen Verweis auf 'name' zurück und zerstören dann die' SpaceShip' -Instanz, dann hätten Sie jetzt einen veralteten Verweis auf den jetzt zerstörten 'name'. –

+0

in C++ 11 Rückgabe von By-Wert ist nicht unbedingt eine schlechte Wahl, und es nicht notwendigerweise auch kopieren. Es gibt _move semantics_ in C++ 11 für alle Standard-Bibliothekstypen implementiert (einschließlich String, Vektor usw.).Es gibt genügend Feinheiten in der C++ - Sprache, wobei einige Szenarien existieren, die eine "Rückgabe nach Wert" effizienter machen als eine "Weitergabe nach Referenz" (aufgrund verschiedener Macken mit temporären Kopien). Für einfache Get-Member-Funktionen ist es jedoch am sinnvollsten, mit reference-to-const zurückzukehren. –

Antwort

0

Auf Ihren letzten Punkt müssen Sie auf jeden Fall viel vorsichtiger sein Ressourcenverwaltung in C++ als in Java. Insbesondere müssen Sie entscheiden, wann ein Objekt nicht mehr benötigt wird. Die Rückgabe als Referenz wirkt sich auf das zurückgegebene Objekt aus. Es fällt nicht auf, wenn das Objekt, das Sie freigeben, unveränderlich ist, aber im Gegensatz zu den Strings von Java ist die C++ - Zeichenfolge veränderbar. Wenn Sie daher name nach Wert zurückgeben und dann Ihre SpaceShip umbenennen, würde der Aufrufer den alten Namen auch nach der Umbenennung sehen. Wenn Sie jedoch als Referenz zurückkommen, sieht der Anrufer eine Änderung, sobald ShaceShip umbenannt wird.

Wenn Sie mit dem Kopieren komplexer Objekte arbeiten, können Sie entscheiden, wie viel kopiert wird, indem Sie eine benutzerdefinierte Implementierung eines Kopierkonstruktors bereitstellen. Wenn Sie sich entscheiden, einen Kopierkonstruktor bereitzustellen, vergessen Sie nicht the rule of three, und überschreiben Sie die anderen beiden.

+0

Und wenn Sie per Referenz zurückkommen und dann das Raumschiff in die Luft sprengen, haben Sie jetzt eine abgestandene Referenz auf 'name' –

+0

Ich denke, ich habe es jetzt, danke für die Antwort –

+0

@ user1937198 Ja, das ist die eine. Vielen Dank! – dasblinkenlight

0

Es „funktioniert“, aber Sie sollten

const string& GetName() const { 

Es kann auch

const WeaponSystem& GetWeaponSystem() const { 

auch auch die folgenden haben vorteilhaft sein müssen, ist class standardmäßig privat, als solche, Ihre Accessorfunktionen sind privat.

0

das, was Sie wissen müssen, ist jeder Getter Ihrer Klasse muss Prototyp aussehen:

const <type> &className::getXXX() const 
{ 
... 
} 

und jeder Setter du so machen:

void className::setXXX(const <type> &) 
{ 
... 
} 

Verwenden Referenz, wenn es möglich ist. Manchmal, mit komplexen Objekt können Sie Zeiger verwenden. Das hängt von Ihrer Code-Struktur ab.

Verwandte Themen