In diesem Falle wird eine temporäre Kopie des Objektes zurückgegeben.
Also aufpassen, wenn Du zum Beispiel Zeiger in der Klasse lagerst.
Dann wird das Objekt kopiert, das Original zerstört, und die Kopie
zurückgegeben. Der Destruktor des Originals wird also am Ende
der Funktion aufgerufen, und dieser zerstört dann die Zeiger.
Da die Kopie aber trotzdem noch die alten Zeiger benutzt, die ja
nun schon freigegeben wurden, kann es so zum Crash kommen.
Deshalb soll man auch für jede Klasse, die Zeiger/Handles verwaltet,
einen Kopiekonstruktor und einen Zuweisungsoperator explizit anlegen,
worin dann richtig kopiert und erzeugt wird.
Das ist die offizielle Vorgehensweise. Einige Compiler können das
wohl optimieren und machen nicht erst eine Kopie, aber das ist
eben nicht offiziell und kann zu ungewünschten Nebeneffekten führen.
Code: Alles auswählen
#include <iostream>
class EineKlasse {
private: int* p;
public: EineKlasse() {
p = new int;
std::cout << "Konstruktor EineKlasse" << std::endl;
}
public: ~EineKlasse() {
if(p) delete p;
std::cout << "Destruktor EineKlasse" << std::endl;
}
public: int getP(void) {
return *p;
}
public: void setP(const int x) {
*p = x;
}
public: EineKlasse(const EineKlasse &ek) {
std::cout << "Kopie-Konstruktor EineKlasse" << std::endl;
p = new int(*ek.p);
}
public: EineKlasse& operator=(const EineKlasse& ek) {
std::cout << "Zuweisungsoperator EineKlasse" << std::endl;
if(this!=&ek) {
if(p) delete p;
p = new int(*ek.p);
}
return *this;
}
};
EineKlasse gib()
{
EineKlasse blubb,b;
blubb.setP( 1111 );
b = blubb; // Zuweisungsoperator =
std::cout << "getP b: " << b.getP() << std::endl;
EineKlasse y(blubb); // Kopie-Konstruktor, erzeugt aus einem Objekt ein neues
std::cout << "getP y: " << y.getP() << std::endl;
return y; // erzeugt neues temporaeres Objekt und gibt diese Kopie zurueck
}
int main (int argc, char *argv[])
{
EineKlasse x = gib();
std::cout << "getP: " << x.getP() << std::endl;
return(0);
}