Frage zum C++ Scopebereich

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Frage zum C++ Scopebereich

Beitrag von milan1612 »

Da die Frage wahrscheinlich echt lächerlich ist, poste ich sie mal lieber hier,
in einem C++ Fourm würden sie mich eh nur auslachen :lol:

Also:

Code: Alles auswählen

class EineKlasse {
};

EineKlasse gib()
{
  EineKlasse blubb();
  //...
  return blubb;
}

int main()
{
  EineKlasse blubb = gib()
  //...
}
Ich erstelle in der function gib() eine Instanz von EineKlasse auf dem Stack.
Wenn ich diese dann zurückgebe verliert sie ja eigentlich ihren Scope und müsste
automatisch gelöscht werden. Ist ein standard-konformer Compiler dazu in
der Lage mitzukriegen dass die Rückgabe noch verwendet wird oder löscht
der ohne Wenn und Aber wenn der Scope verlassen wird?

Danke :)
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Frage zum C++ Scopebereich

Beitrag von Danilo »

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);
}
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

Ahh, ich danke dir :allright:
Sehr anschauliches Beispiel, das erklärt einiges über das ich mich schon oft gewundert habe.
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Antworten