Kann man in einem Ctor einen anderen, überladenen Ctor aufrufen?



  • class Test
    {
    public:
    Test() { ... }
    Test(int x) : m_x(x) { Test() }
    

    Geht sowas?



  • Nope.



  • Lösung: schreib ne private Methode die du in beiden Ctoren aufrufst und die den gemeinsamen Code enthält



  • Konstruktoren kann man nie aufrufen wie methoden, eine alternative wäre vieleicht vererbung, denn den Konstruktor der Basisklasse kann man im Konstruktor der Abgeleiteten Klasse aufrufen.

    class A{
    public:
        A(int wert){}
    }
    
    classB: public A{
    public:
       B(int w1, int w2): A(w1){}
    }
    

    nun wird der Konstruktor von A in B aufgerufen, allerdings muss das Objekt der Klasse A bereits Existieren, bevor der Konstruktor aufgerufen werden kann, deshalb steht der Ausdruck auch vor der Klammer des Konstruktors.



  • Danke.

    Ich habe heute nämlich gesehen, dass in C# sowas möglich ist. Da haben meine Frickelsensoren alarm geschlagen, wer sowas macht. Und weil ich gerne immer wieder C++ zum Vergleich heranziehe (nette Möglichkeit, vorhandenes Wissen nochmal zu prüfen), hab ich mich gefragt, ob das eben auch geht.

    Danke nochmal.



  • Ergänzung: das was du geschrieben hast wird compilieren, allerdings wird nicht das passieren was du möchtest. (Davon abgesehen dass du ein ";" vergessen hast, aber wenn du das ergänzt würde es compilieren.)

    Was passieren wird ist dass beim Aufruf von "Test::Test(int x)" zuerst "Test::m_x" initialisiert wird, und dann wird ein unbenanntes Objekt vom Typ "Test" angelegt (unter verwendeung des ctor "Test::Test()", und gleich wieder zerstört.

    IIRC gibt es ein Proposal den Aufruf von Konstruktoren aus anderen Konstruktoren zu erlauben. Die Syntax sieht dabei dann aber anders aus. IIRC ca. so:

    class Test
    {
    public:
        Test() { ... }
        Test(int x) : Test() { m_x = x; }  
    };
    


  • Ne, ich hab nicht nur das Semikolon, sondern auch die schließende Klammer der Klasse vergessen. 🙂
    Ja, genau so wird in C# auch ein Konstruktur aus einem anderen heraus aufgerufen. Ich finde das aber absolut hässlich und sinnlos. Wenn zwei Konstruktoren gemeinsamen Code haben, finde ich die bereits erwähnte (private) gemeinsame Methode optimal. Wenn sich die Konstruktoren gegenseitig aufrufen, resultiert das doch zwangläufig in Frickelcode... und es ist eben unnötig.

    C# scheint mir aber ohnehin voll die Frickelsprache zu sein. Gerade lese ich von den Destruktoren, dass die durch den GC erst zu einem unbestimmten Zeitpunkt aufgerufen werden. Deshalb gibt es das Interface IDispose, das einen Destruktor-Ersatz als Methode bereitstellt, damit der Benutzer ihn (den Destruktor) gewissermaßen direkt aufrufen kann. Dann muss man den GC aber mitteilen, dass der den Destruktor nicht mehr aufrufen darf, alternativ könnte man den GC noch per Hand anstoßen, damit er aufräumt.

    Mir gefällt es nicht.



  • wird in C++09 möglich sein. ("delegate constructors" IIRC)



  • C# scheint mir aber ohnehin voll die Frickelsprache zu sein. Gerade lese ich von den Destruktoren, dass die durch den GC erst zu einem unbestimmten Zeitpunkt aufgerufen werden. Deshalb gibt es das Interface IDispose, das einen Destruktor-Ersatz als Methode bereitstellt, damit der Benutzer ihn (den Destruktor) gewissermaßen direkt aufrufen kann.

    Das hat nichts damit zu tun dass C# "frickelig" ist, sondern einfach damit dass C# GC verwendet. Da aber nicht alle Resourcen vom GC kontrolliert werden, und manche Resourcen deterministisch freigegeben werden müssen (Files, Datenbank Connections, ...), muss man sowas wie IDisposable verwenden.

    Dann muss man den GC aber mitteilen, dass der den Destruktor nicht mehr aufrufen darf, alternativ könnte man den GC noch per Hand anstoßen, damit er aufräumt.

    Nö, man muss dem GC garnix mitteilen. Es ist bloss effizienter wenn man es tut.


Anmelden zum Antworten