Warum kann man im Konstruktor keinen anderen Konstruktor der selben Klasse aufrufen?



  • Warum kann man im Konstruktor keinen anderen Konstruktor der selben Klasse aufrufen?



  • wegen der entstehenden Rekursion



  • Rehakles schrieb:

    Warum kann man im Konstruktor keinen anderen Konstruktor der selben Klasse aufrufen?

    Weil es der derzeitige C++ Standard nicht vorsieht. *Im* Konstruktor macht aus Sicht des C++ Object-Modells auch keinen Sinn, da hier alle Member und Basisklassen bereits initialisiert sind.

    Ein Forwarding zu einem anderen Ctor innerhalb einer Initialisierungsliste wird vielleicht in einem späteren C++ Standard mal erlaubt sein.

    Derzeit ist das nicht möglich, da sonst Basisklassen entweder mehrfach initialisiert werden könnten (der tatsächliche Aufruf von Ctoren über die Initialisierungsliste ist unabhängig von der dort angegebenen Reihenfolge - entscheidend ist die Deklarationsreihenfolge. Das heißt auch: Basisklassen vor der aktuellen Klasse) oder aber der Compiler sich immer merken müsste, dass ein anderer Ctor das Objekt bereits teilweise initialisiert hat. Das würde Kosten verursachen die wohl dem Zero-Cost-Principle widersprechen.



  • Hm, versteh ich nicht.

    class Rehakles
    {
    public:
    	Rehakles(int a, int b)
    	{
    	}
    
    	Rehakles(int a)
    		: Rehakles(a, 5)
    	{
    	}
    };
    

    Wenn ich jetzt den 2. Konstruktor aufrufe um das Objekt zu konstruieren, dann wird doch in diesem nur einmal der erste Konstruktor aufgerufen, und das wars??
    Wo soll da eine Rekursion entstehen?



  • T::T (int a, int b)
        :
    m_a(a),
    m_b(b)
    {
    }
    
    T::T (int a)
        :
    m_b(4),
    T(a,0)
    {
    }
    

    Was nun?

    MfG SideWinder



  • achso hab das falsch verstanden, dachte du meintest

    class a {
      a foo;
    public:
      a(int i) : foo(i) { }
    };
    

    Aber Hume hat dir ja richtig geantwortet 🙂



  • Rehakles schrieb:

    Warum kann man im Konstruktor keinen anderen Konstruktor der selben Klasse aufrufen?

    Weil C++ scheisse ist. In Java und C# gehts.



  • asSimpleAsItGets schrieb:

    Rehakles schrieb:

    Warum kann man im Konstruktor keinen anderen Konstruktor der selben Klasse aufrufen?

    Weil C++ scheisse ist. In Java und C# gehts.

    "For every problem, there is a solution that is simple, neat, and wrong."
    - H. L. Mencken

    Schnell noch problem/solution durch question/answer ersetzen und Bingo 😃





  • "wrong" ist in dem Fall wohl eindeutig Ansichtssache ...



  • Warum kann man im Konstruktor keinen anderen Konstruktor der selben Klasse aufrufen?

    Geht doch. 😉

    #include <iostream>
    using std::cout;
    const char NL = '\n';
    
    class X
    { 
    public: 
        X(int a, int b) 
        { 
            cout << "ctor mit 2 Argumenten" << NL;
        } 
    
        X(int a) 
        { 
            cout << "ctor mit 1 Argument" << NL;
            X(a,5); 
        } 
    }; 
    
    int main()
    {
        X x(42);
    }
    

    In der Initialisierungsliste sucht er eben nur Konstruktoren von Basisklassen.

    Selbst die Rekursion ist erlaubt! Warum auch nicht? 😋

    #include <iostream>
    using std::cout;
    const char NL = '\n';
    
    class X
    { 
    private:
        static int counter_;
    public: 
        X(int a, int b) 
        { 
            cout << "ctor mit 2 Argumenten" << NL;
            if(counter_<10) X(5);
        } 
    
        X(int a) 
        { 
            cout << "ctor mit 1 Argument" << NL;
            ++counter_;
            X(a,5); 
        } 
    }; 
    
    int X::counter_=0;
    
    int main()
    {
        X x(42);
    }
    


  • Erhard Henkes schrieb:

    Geht doch. 😉

    Dir ist aber schon klar, dass du mit X(a,5); nur ein temporaeres Objekt erstellst, oder?



  • Klar, kann man hier schön sehen, wie das Objekt durch den Stack "geistert":

    #include <iostream>
    using std::cout;
    const char NL = '\n';
    
    class X
    { 
    private:
        static int counter_;
    public: 
        X(int a, int b) 
        { 
            cout << "ctor mit 2 Argumenten  " << this << NL;
            if(counter_<10) X(5);
        } 
    
        X(int a) 
        { 
            cout << "ctor mit 1 Argument    " << this << NL;
            ++counter_;
            X(a,5); 
        } 
    }; 
    
    int X::counter_=0;
    
    int main()
    {
        X x(42);
        cout << NL << &x << NL;
    }
    

    Das war aber nicht das Thema, sondern:
    Warum kann man im Konstruktor keinen anderen Konstruktor der selben Klasse aufrufen?
    Genau das habe ich oben getan! 😃 😃
    Das Objekt, das mit der Adresse &x ausgegeben wird, entsteht zu Beginn durch X(int a). Keine Ahnung, welcher Art die restlichen Objekte sind. Alles Geister! Vielleicht kann man damit testen, wie groß der Stack ist (counter_ groß genug machen. 😉 ). Fehlt nur noch eine Fehlerabfrage und die Ausgabe der Stackgröße. 🙂 👍

    Geht natürlich auch mit nur einem Konstruktor:

    #include <iostream>
    using std::cout;
    const char NL  = '\n';
    const char TAB = '\t';
    class X
    { 
    private:
        static int counter_;
    public: 
        X(int a) 
        { 
            cout << counter_ << TAB << this << NL;
            ++counter_;
            if(counter_<20) X(5);
        } 
    }; 
    
    int X::counter_=0;
    
    int main()
    {
        X x(42);
        cout << NL << &x << NL;
    }
    


  • Bashar schrieb:

    "wrong" ist in dem Fall wohl eindeutig Ansichtssache ...

    Entschuldige. Ich dachte wir wären hier in einem technischen Umfeld in dem Antworten der Art "Weil X scheiße ist" auf Fragen wie die hier gestettelte nicht "Ansichtssache" sondern eindeutig zu wenig für eine sinnvolle Diskussion sind (imo ist sowas eher ein Zeichen für mangelnde Reife und begrenzte Hirnkapazität).

    Die Aussage "C++ ist scheiße" ist faktisch falsch. Man kann über die Sinnhaftigkeit einzelner Sprachfeatures diskutieren, man kann Sprachfeatures vergleichen, man kann verschiedene Sprachen vergleichen und dabei in einem eingeschränkten Kontext auch gerne mal kräftige Worte wie "käse" verwenden, man kann sicher auch mal "Bauchgefühle" artikulieren (solange dabei klar ist, dass es sich dabei um solche handelt),
    aber globale Aussagen wie "C++ ist Scheiße", "Java ist Dreck", "Microsoft stinkt" usw. sind Kindergarten.

    Hätte nicht gedacht, dass du das anders siehst...



  • HumeSikkins schrieb:

    Ich dachte wir wären hier in einem technischen Umfeld in dem Antworten der Art "Weil X scheiße ist" auf Fragen wie die hier gestettelte nicht "Ansichtssache" sondern eindeutig zu wenig für eine sinnvolle Diskussion sind (imo ist sowas eher ein Zeichen für mangelnde Reife und begrenzte Hirnkapazität).

    Jup.

    Die Aussage "C++ ist scheiße" ist faktisch falsch.

    Mag sein, darauf hab ich mich aber überhaupt nicht bezogen. Ich hab lediglich vermutet, dass dein Zitat auf das Java-Feature, in Konstruktoren den Aufruf anderer überladener Konstruktoren derselben Klasse zuzulassen, bezogen war. Da du meine Reaktion aber anscheinend in den völlig falschen Hals bekommen hast, hab ich dich wohl falsch verstanden. Naja, wenn du das auf den anderen Satz bezogen hast, ist das wohl jetzt geklärt 🙂


Anmelden zum Antworten