default constructor



  • Hallo
    wahrscheinlich sehe ich vor lauter Bäumen den Wald gerade nicht:

    Ich habe folgende Klasse (relevanter Ausschnitt)

    class foo {
     public:
      foo();
      foo(double Bar);
      ~foo();
      void setBar(double Bar);
      double getBar()
     private:
      double bar;
    }
    
    foo::foo() {
     foo(1.0);
    }
    
    foo::foo(double Bar) {
     this->setBar(Bar);
    }
    
    void foo::setBar(double Bar) {
     bar = Bar;
    }
    
    double foo:getBar() {
     return bar;
    }
    

    dann habe ich folgenden Aufruf:

    double temp;
     foo *FooBar = new foo();
     temp = FooBar->getBar();
     //temp != 1 . warum???????
    

    Und temp ist dann ungleich eins, warum?

    Nachschlag:

    double temp;
     foo *FooBar = new foo(7.89);
     temp = FooBar->getBar();
     //Hier ist temp gleich dem Wert, den ich dem Konstruktor übergeben habe
    


  • Hallo

    machs doch einfacher

    class foo {
     public:
      foo(double Bar = 1.0);
      ~foo();
      void setBar(double Bar);
      double getBar()
     private:
      double bar;
    }
    
    foo::foo(double Bar) {
     this->setBar(Bar);
    }
    
    void foo::setBar(double Bar) {
     bar = Bar;
    }
    
    double foo:getBar() {
     return bar;
    }
    

    bis bald
    akari



  • Danke,
    wie gesagt, wald vor lauter Bäumen nicht gesehen 🙂



  • du kannst den Konstruktor nich aufrufen (ausser bei deklaration einer Variablen)
    d.h. in deiner ersten variante müsste der Konstruktor so aussehen:

    foo::foo()
    {
       setBar(1.0);
    }
    

    allerdings wenn du unbedingt nen wert haben willast dann is akaris variante die bessere.

    Mfg Shade37337



  • Hallo,
    um noch mal auf das "warum?" zurückzukommen - das Problem ist folgende Zeile:

    foo::foo() {
     foo(1.0);
    }
    

    Im Gegensatz zu z.B. Java unterstützt C++ kein "Constructor Chaining". D.h. du kannst im Konstruktor eines Objekts nicht einen anderen Konstruktor für das selbe Objekt aufrufen. Dein Code sorgt also nicht dafür, dass für dein default-konstruiertes Objekt der double-Konstruktor aufgerufen wird. Vielmehr wird in der Zeile foo(1.0) ein anonymes, temporäres Objekt erzeugt, mit 1.0 initialisiert und mit erreichen des Semikolons wieder zerstört. Dein Originalobjekt bleibt von dieser Aktion vollkommen unberührt.

    Code-Duplikation in Konstruktoren vermeidet man in C++ zum einen mit Default-Parametern (so wie es akari gezeigt hat). Eine Alternative ist die Verwendung einer gemeinsamen Methode (z.B. init):

    class foo {
     public:
      foo();
      foo(double Bar);
      ~foo();
      void setBar(double Bar);
      double getBar()
     private:
      double bar;
      void init(double d);
    }
    foo::foo() {
      init(1.0);
    }
    foo::foo(double d) {
      init(d);
    }
    void foo::init(double d) {
      // gemeinsamer Initialisierungscode
    }
    

    Leider hat diese Technik den Nachteil, dass innerhalb von init nur Zuweisungen stattfinden können, nicht aber Initialisierungen.


Anmelden zum Antworten