Constructor => Funktion : this übergeben



  • ist das hier:

    class1::class1(){ 
        init(*this); 
    }
    

    denn überhaupt definiert?
    eigtl existiert das objekt dort ja noch gar nicht...

    bb



  • unskilled schrieb:

    ist das hier:

    class1::class1(){ 
        init(*this); 
    }
    

    denn überhaupt definiert?
    eigtl existiert das objekt dort ja noch gar nicht...
    bb

    Uups, ich dachte, er macht init(this). this aus dem Ctor rauszugeben, mache ich öfters. Aber dieser Zeiger wird dann erst nach Ablauf des Ctors dereferenziert.

    Andererseits ist das Aufrufen der init-Methode nicht genauso kritisch, immerhin existiert das Objekt noch nicht. Aber ich bin sicher, daß ich dauernd sehe, wie Leute aus einem Ctor eigene Methoden aufrufen.



  • Huch!
    Ich habe auch nur init(this) im Code stehen. Sorry, fehler meinerseits 😞

    class1::class1(){
        init(this);
    } 
    
    void class1::init(class1* ptr){
    ptr->value = "fool";
    //...
    }
    

    So (s.o.) ist das jetzt aber völlig in Ordnung, oder wie jetzt?



  • class class1
    {
    public:
      class1()
      {
        init();
      }
    
      void init()
      {
        //...
      }
    };
    

    Wäre in Ordnung - allerdings weiß ich nicht, wieso man dann noch ne init-fkt schreibt, wenn der ctor eh nichts anderes macht... aber ist sicherlich geschmackssache...

    bb



  • unskilled schrieb:

    Wäre in Ordnung - allerdings weiß ich nicht, wieso man dann noch ne init-fkt schreibt, wenn der ctor eh nichts anderes macht... aber ist sicherlich geschmackssache...

    Also ich nutze das ab und an mal wenn ich mehrere ctors habe in denen sich ein Code wiederholt.



  • volkard schrieb:

    unskilled schrieb:

    ist das hier:

    class1::class1(){ 
        init(*this); 
    }
    

    denn überhaupt definiert?
    eigtl existiert das objekt dort ja noch gar nicht...
    bb

    Uups, ich dachte, er macht init(this). this aus dem Ctor rauszugeben, mache ich öfters. Aber dieser Zeiger wird dann erst nach Ablauf des Ctors dereferenziert.

    Andererseits ist das Aufrufen der init-Methode nicht genauso kritisch, immerhin existiert das Objekt noch nicht. Aber ich bin sicher, daß ich dauernd sehe, wie Leute aus einem Ctor eigene Methoden aufrufen.

    Das Objekt ist zwar im Ctor-Rumpf noch nicht fertig konstruiert, allerdings sind die Membervariablen zu dem Zeitpunkt bereits alle initialisiert - sozusagen ein "Halbleben" des zu konstruierenden Objekts. Methoden, die (semantisch gesehen) nur mit den Membervariablen arbeiten (z.B. so eine init()-Methode), sind daher in Ordnung. Den Aufruf von Methoden, die semantisch und programmlogisch gesehen das neue Objekt als ganzes behandeln, sollte man eher vermeiden, weil das Objekt streng genommen eben noch nicht existiert.



  • pumuckl schrieb:

    Das Objekt ist zwar im Ctor-Rumpf noch nicht fertig konstruiert, allerdings sind die Membervariablen zu dem Zeitpunkt bereits alle initialisiert - sozusagen ein "Halbleben" des zu konstruierenden Objekts. Methoden, die (semantisch gesehen) nur mit den Membervariablen arbeiten (z.B. so eine init()-Methode), sind daher in Ordnung. Den Aufruf von Methoden, die semantisch und programmlogisch gesehen das neue Objekt als ganzes behandeln, sollte man eher vermeiden, weil das Objekt streng genommen eben noch nicht existiert.

    Also meines Wissens existiert das Objekt sehr wohl, aber eben nur bis zu der Klasse, in deren Ctor man gerade ist. Alle Unterklassen sind vollständig initialisiert, und wenn man sich im Rumpf des Ctors befindet, ist auch die aktuelle Klasse vollständig.

    Einzige Ausnahme: Die vtbl. Meines Wissens kann man also mit einem Objekt im Rumpf des Ctors ganz normal arbeiten - so lange man weiß (und beachtet), dass Polymorphie in Konstruktoren nicht funktioniert. Irre ich mich?

    Stefan.



  • unskilled schrieb:

    class class1
    {
    public:
      class1()
      {
        init();
      }
    
      void init()
      {
        //...
      }
    };
    

    Wäre in Ordnung - allerdings weiß ich nicht, wieso man dann noch ne init-fkt schreibt, wenn der ctor eh nichts anderes macht... aber ist sicherlich geschmackssache...

    bb

    Moin.
    Also urpsrünglich war die init() dafür gedacht, weil der Code in mehreren Construktoren identisch ist und somit dann nicht zig mal im Quelltext steht.
    Zu der Idee mit dem Pointer: Das ganze ist daher entstanden, weil ich mit Vererbung arbeite:

    class class1
    {
    protected:
      int int1, int2;
      std::string foo;
    
    public:
      class1() { }
    
     private:
         init();
    
        class1::init(){
            int1 = 0;
            int2 = 1;
        }    
    };
    
    class class2 : public class1 {
    
    public:
      class2() {
      }
    
     class2::class2() : Class1() {
    	foo="bar";
    };
    

    Class2 ist nicht das einzige Objekt, was von Class1 erbt. All diese Klassen haben gemeinsam, dass von den Membervar. -vereinfacht- nur der string foo unterschiedlich ist. Da jedoch bei Aufruf des Konstruktors der Class2 zuerst der Konstruktor von der Basisklasse abgearbeitet wird, kann ich die Zuweisung nicht über den Konstruktor aufrufen, wenn die Zuweisung bei diesem (class2) mit standardkonstruktor gelöst wird...Einzige weitere Möglichkeit die ich grad seh ist es die Zuweisung von foo über eine eigene Memberfunktion in der Basisklasse zu machen (z.B. setString(std::string) oder sowas)...

    Weitere Frage zu dem Pointer: Ist es denn nicht mötig, die Member zu dem jewieligen Objekt zu spezifizieren (this->....)? Aus java weiss ich dass this explizit notwendig ist...



  • Ich füchte, Du mußt erstmal 50 Seiten weiterlesen. Da steht bestimmt alles drin.
    Als Leitfaden gebe ich Dir mal: Du brauchst die init-Funktion gar nicht. Das wird normalerweise im Konstruktor gemacht. Selten mal gibt es zwei Konstruktoren derselben Klasse, die sich ein init derselben Klasse teilen. Die init-Funktion ist IMMER private, niemals protected oder noch schlimmer. Konstruktoren der Basisklasse ruft man meist mit Parametern auf.



  • volkard schrieb:

    Ich füchte, Du mußt erstmal 50 Seiten weiterlesen. Da steht bestimmt alles drin.
    Als Leitfaden gebe ich Dir mal: Du brauchst die init-Funktion gar nicht. Das wird normalerweise im Konstruktor gemacht. Selten mal gibt es zwei Konstruktoren derselben Klasse, die sich ein init derselben Klasse teilen. Die init-Funktion ist IMMER private, niemals protected oder noch schlimmer. Konstruktoren der Basisklasse ruft man meist mit Parametern auf.

    wo denn 50 Seiten weiterlesen?



  • SelfischCatcher schrieb:

    wo denn 50 Seiten weiterlesen?

    In Deinem C++-Buch, für Java-Umsteiger vielleicht das hier http://oreilly.com/catalog/9780596002985/



  • hm...dumm nur, dass ich kein solches Umsteigerbuch habe... 😞
    Intressieren würd mich trotzdem, worauf in neinen Fragen du das "erst lesen" bezogen hast 🙂



  • Xebov schrieb:

    unskilled schrieb:

    Wäre in Ordnung - allerdings weiß ich nicht, wieso man dann noch ne init-fkt schreibt, wenn der ctor eh nichts anderes macht... aber ist sicherlich geschmackssache...

    Also ich nutze das ab und an mal wenn ich mehrere ctors habe in denen sich ein Code wiederholt.

    hab ich auch mal gemacht - aber dann hatte iwer den tipp, die member noch mal zu kapseln:

    struct list
    {
      struct _m
      {
        node_base anchor_begin;
        node_base anchor_end;
        size_type length;
        internal_allocator_type alloc;
    
        _m() : anchor_begin(&anchor_end, nullptr), anchor_end(nullptr, &anchor_begin), length(0) {}
      };
    
      list() {}
      list(size_t count, const_reference = value_type())
      {
        insert_n(count, const_reference);
      }
    };
    

    bb


Anmelden zum Antworten