Konstruktorkette läuft nicht wie gedacht



  • asdsaddsasds schrieb:

    - Eine Klasse beginnt immer mit private, eine struct mit public.

    Was soll denn der Quatsch? Bitte immer erst "public", dann "private". Egal, ob class oder struct. Diejenigen, die diese Klasse später mal benutzen, werden es dir danken. Dann sehen sie nämlich sofort den relevanten (public) Teil, der uninteressante Krams (private) gehört nach unten.



  • manni66 schrieb:

    Konstruktorkette - was soll das sein?

    hallo2::hallo2(string name) : hallo1(name)
    

    Das hier. Oder auch deligierender Konstruktor (so habe ich das mal im Englischen gefunden)

    asdsaddsasds schrieb:

    ...

    Wo mische ich denn C mit C++ ?



  • daddy_felix schrieb:

    Es gibt keinen Konstruktor, der zwei strings annimmt. Deshalb die Fehlermeldung.

    Ich glaube, du möchtest sowas:

    hallo2::hallo2(const std::string& halloString1, const std::string& halloString2)
    : hallo1(halloString1),
      namehallo2(halloString2)
    {}
    

    Es funktioniert jetzt. Vielen Dank 😃



  • AnanasPilot schrieb:

    Oder auch deligierender Konstruktor (so habe ich das mal im Englischen gefunden)

    Ein delegating constructor ist so etwas:

    class Foo {
    public: 
      Foo(char x, int y) {}
      Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int)
    };
    

    http://en.cppreference.com/w/cpp/language/initializer_list



  • AnanasPilot schrieb:

    Wo mische ich denn C mit C++ ?

    Hier

    hallo2 *hip = new hallo2(h1, h2);
    


  • manni66 schrieb:

    ...

    Achso, doch nochmal was anderes 😕
    Die Konstruktorkette wurde mir so von meinem Dozenten vorgestellt, wie ich sie in meinem Beispielprogramm geschrieben habe. Muss das morgen auch sehr wahrscheinlich in einem Testat verwenden.
    Wir bekommen dann aber auch vorgefertigte Klassen und müssen dann Methoden erweitern/schreiben.

    asdsaddsasds schrieb:

    ...

    Und deine Lösung mit unique_ptr ist dann reines c++?

    Mein Dozent ist sehr bemüht darin die Dinge überschaubar zu halten. Ich kann noch nicht einordnen was Sinn ergibt und was nicht.
    Vielleicht wird alles auch erst spezieller wenn es in die Wahlmodule geht. Keine Ahnung 😕



  • AnanasPilot schrieb:

    Und deine Lösung mit unique_ptr ist dann reines c++?

    Ich bin jetzt nicht so bewandert in C oder C++, daher sollte man mich ruhig korrigieren.

    Als erstes solltest du alle Objekte, die du mit new anlegst auch mit delete löschen. Sonst entsteht ein memory leak. Dein Code sollte dann eher so aussehen.

    // erst einmal mit nullptr initialisieren.
    hallo2 *hip = nullptr;
    
    try
    {
      // versuche es zu erzeugen.
      hip = new hallo2(h1, h2);
    catch( std::exception const & e )
    {
      // Fehlerbehandlung falls das Objekt nicht erzeugt werden konnte
    }
    
    // Prüfen ob dein Objekt richtig angelegt werden konnte.
    if( nullptr == hip )
    {
      // Falls nicht, hier kommt Fehlerbehandlung 
    }
    
    // Hier kommt der Arbeitscode
    
    // Wenn du fertig bist
    
    // Prüfen ob nicht eine andere Instanz aufgeräumt hat.
    if( hip != nullptr )
    {
      // falls nicht, dann räumst du auf.
      delete hip;
      hip = nullptr
    }
    

    Für doofe wie mich ist das ganze zu kompliziert. Deswegen verwende ich entweder shared_ptr wenn viele dieses Objekt nutzen oder unique_ptr, wenn ich sicher bin, dass nur ich das Objekt nutze. Es wird dann automatisch aufgeräumt 👍

    Dann wären da noch Nebenbaustellen



  • Kurze Ergänzung zu asdsaddsasds Aussage:
    Du musst den Pointer nach dem delete nicht ein nullptr zuweisen. (Eventuell wenn du den gleichen Pointer nochmal verwenden willst, aber das ist eher untypisch).

    Aber in c++ solltest du dir angewöhnen sogenannte smart pointer zu Verwenden, wenn du dynamisch angelegten Speicher benötigst (std::unique_ptr oder std::shared_ptr).

    In deinem Fall, AnanasPilot, ist die Frage warum überhaupt dynamisch. Warum nicht einfach:

    hallo2 hip(h1, h2);
    


  • asdsaddsasds schrieb:

    AnanasPilot schrieb:

    Wo mische ich denn C mit C++ ?

    Hier

    hallo2 *hip = new hallo2(h1, h2);
    

    Das ist C++. C hat kein new. Was du meinst ist low level C++.



  • out schrieb:

    asdsaddsasds schrieb:

    AnanasPilot schrieb:

    Wo mische ich denn C mit C++ ?

    Hier

    hallo2 *hip = new hallo2(h1, h2);
    

    Das ist C++. C hat kein new. Was du meinst ist low level C++.

    Ist es nicht das äquivalent zu (x)alloc?



  • asdsaddsasds schrieb:

    out schrieb:

    asdsaddsasds schrieb:

    AnanasPilot schrieb:

    Wo mische ich denn C mit C++ ?

    Hier

    hallo2 *hip = new hallo2(h1, h2);
    

    Das ist C++. C hat kein new. Was du meinst ist low level C++.

    Ist es nicht das äquivalent zu (x)alloc?

    Tatsächlich nicht. Zumindest zu dem malloc / free, wie ich es kenne.
    Mit new / delete wird der entsprechende Konstruktor aufgerufen und die nötigte Speichergröße automatisch bestimmt. Das hast du bei malloc und free nicht.



  • Schlangenmensch schrieb:

    asdsaddsasds schrieb:

    out schrieb:

    asdsaddsasds schrieb:

    AnanasPilot schrieb:

    Wo mische ich denn C mit C++ ?

    Hier

    hallo2 *hip = new hallo2(h1, h2);
    

    Das ist C++. C hat kein new. Was du meinst ist low level C++.

    Ist es nicht das äquivalent zu (x)alloc?

    Tatsächlich nicht. Zumindest zu dem malloc / free, wie ich es kenne.
    Mit new / delete wird der entsprechende Konstruktor aufgerufen und die nötigte Speichergröße automatisch bestimmt. Das hast du bei malloc und free nicht.

    Stimmt 👍 Ist bei mir schon etwas länger her, danke für die Erinnerung 😃



  • Danke für alle Antworten 🙂



  • asdsaddsasds schrieb:

    Dein Code verursacht deswegen ein Memory-Leak. Besser wäre folgendes

    #include <memory>
    #include <cstdlib>
    
    int main( int argc , char ** argv )
    {
      std::string h1( "1" );
      std::string h2( "2" );
    
      std::unique_ptr< hallo2 > hip( h1 , h2 );
      std::cout << hip->getHallo1() << std::endl;
    
      system( "pause" );
    
      return EXIT_SUCCESS;
    }
    

    den smart pointer kann man sich sparen:

    int main( int argc , char ** argv )
    {
    [...]
      hallo2 hip( h1 , h2 );
      std::cout << hip.getHallo1() << std::endl;
    [...]
    }
    


  • Sollte man sich sparen. Steht da hoffentlich auch nur, wegen des noch unsinnigeren news im Anfangspost.