statische Methoden und Initialisierungsliste



  • Hallo,

    ich versuche gerade statische Methoden einzuführen. Bei der Klasse Console geht es ganz gut, aber bei Draw mit Initialisierungsliste komme ich nicht weiter.

    Hier das Beispiel für Console :
    .h

    class Console
    {
        Console();
    
    public:
    
        static Console& getInstance();
    
    // ... 
    
    };
    
    extern Console& console;
    

    .cpp

    Console::Console()
    {
        setDefaultWindow();
    }
    
    Console& Console::getInstance()
    {
        static Console instance;
        return instance;
    }
    
    // ...
    
    Console& console = Console::getInstance();
    

    Draw
    .h

    class Draw
    {
    
    public:
    
        Draw( Console& console ) : console( console )
        {
            getDefaultCoords();
            getDefaultChars();
        }
    // ...
    };
    

    Hier weiß ich nichtmal, wie ich wie bei Console den Konstruktor in .h und .cpp aufteile.



  • Ein statischer Konstruktor würde ja auch gar keinen Sinn ergeben. 😕
    Ferner vermute ich, du willst Draw zu einer Funktion machen, nicht zu einer Klasse. Das ist schließlich nicht Java.

    EDIT:

    Hier weiß ich nichtmal, wie ich wie bei Console den Konstruktor in .h und .cpp aufteile.

    Hast du doch schon gemacht? Angenommen, du meintest eigentlich Draw, dann müsste das so aussehen:

    // Header
        Draw( Console& console );
    
        // Source
        Draw::Draw( Console& console ) : console( console )
        {
            getDefaultCoords();
            getDefaultChars();
        }
    


  • Danke. Super, dann wäre dies schon gelöst

    Richtig, Draw . Ich meinte eben "wie bei" Console .

    Aber die Initialisierungsliste macht mir zu schaffen. Ich weiß einfach nicht, was zu wem gehört. Aber dazu später. Muss jetzt weg.



  • lemon03 schrieb:

    Hallo,

    ich versuche gerade statische Methoden einzuführen.

    Warum?
    Wenn Console ein Singleton ist, warum übergibst du sie an Draw?



  • Weil Draw die Werte der Console benötigt.

    Ich hatte davor das Problem, das ich in der main() einmal Console console; und Draw draw; aufgerufen hatte und Console console nochmal in Draw, um dort bekannt zu machen. Das hatte dazu geführt, das die jeweiligen Werte rein gar nicht zu einander gepasst hatten.

    Dies hatte mir man mit zwei Instanzen erklärt, die durch diese Aufrufe entstanden sind.

    Als Ausweg gab es die Lösung, Draw mit Parameter aufzurufen Draw draw( console ); , dazu die Initialisierungsliste in Draw. Das ist auch wunderbar gelaufen, danke dafür. Aber inzwischen habe ich andere Codes gesehen, die nicht ständig in den Funktionen die Klassen übergeben müssen und bin auf eben Singleton access gestoßen. Dies will ich versuchen, wenn möglich, zu übernehmen.

    Das alles mag jetzt evtl hinfällig(?) sein, dies ist aber die Hintergrundgeschichte.

    Dazu möchte ich noch anmerken, das dies noch alles recht neu für mich ist, habe erst vor kurzem meine erste Klasse geschrieben, und diese Sache ist doch recht schwierig für mich. (Allerdings waren auch mal Dinge wie vector für mich recht unüberschaubar, weshalb ich nicht ganz schwarz sehe)



  • Wenn Console ein Singleton isr, kann Draw sich dieses Singleton jederzeit selber mit der instance Funktion besorgen => kein Parameter.

    Ob das mit dem Singleton eine gute Idee ist, steht auf einem anderen Blatt.



  • Danke. Nur fürs Protokoll, in welchen Fällen und weshalb ist Singleton keine gute Idee?

    Für eine Klasse alleine fand ich das Ding super. Vielleicht funktioniert es bei mehreren Klassen nicht mehr? Ist aber schon fast Borg-Technologie für mich 😉

    edit: muss mich jetzt aber entschuldigen ... muss mal weg



  • lemon03 schrieb:

    Danke. Nur fürs Protokoll, in welchen Fällen und weshalb ist Singleton keine gute Idee?

    Singleton stellt sicher, dass es nur genau ein Objekt dieses Typs gibt. Dieses Objekt ist global. Wann braucht man das wirklich?

    Was auch immer deine Console macht: darf es immer nur eine Instanz geben? Oder brauchst du im Moment nur eine?



  • Meine Console setzt/öffnet ein Konsolenfenster und legt/liest dessen Werte. Dafür werden auch einige WinAPI-Funktionen benutzt.

    Im alten Code könnte man zwar mehrere Instanzen von Console erstellen, gezeigt wird aber immer nur die Instanz, die im Code als letzte aufgerufen wurde. Ich weiß jetzt auch gar nicht, ob mehrere Konsolenfenster gleichzeitig überhaupt möglich sind. Wenn es die WinAPI erlaubt, könnte ich mir durchaus kleine Spielereien damit vorstellen.

    Aber auch wenn nicht, könnte es eine Berechtigung für mehrere Instanzen geben, bei denen mehrere Konsolen gefüllt werden, die dann nacheinander gezeigt werden. Geschwindigkeitstechnisch gibt es dafür aber noch keine Notwendigkeit. Kann auch sein, das es so etwas schon in den ConsoleScreenBuffer-Funktionen der WinAPI gibt.

    Ich habe das jetzt etwas ausführlicher beschrieben, weil ich nicht genau wusste, worauf die Fragen abzielen, gibt ja doch immer einige Fallstricke hier 😉
    Um es kurz zu machen, mehrere Instanzen wären vielleicht interessant, aber brauchen tue ich sie nicht 🙂



  • Dann brauchst du auch kein Singleton. Warum willst du dich damit zusätzlich einschränken?



  • Gibt es denn eine andere Möglichkeit, Klassen in Funktionen nicht übergeben zu müssen?

    Ich habe zB diese kleine Funktion,

    void ready( const int& col )
    {
        /*SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ),
                                 static_cast<WORD> ( col ) );*/
        console.setCursorColor( col ); //neu
        console.showCursor();          //neu
        std::cout << "\n\nready";
        std::cin.sync();
        std::cin.get();
    }
    

    welche ich sonst ständig ready( console ); aufrufen müsste, was nicht gewünscht ist.

    Ich dachte bisher, Funktionen so zu schreiben, die sichtbar nur die Werte übergeben, die auch benutzt werden, wäre ziemlich kompliziert. Also zB

    drawDot( x, y, color );
    

    statt

    drawDot( console, draw, x, y, color );
    

    Durch den Singleton access erschien mir das in greifbare Nähe.



  • Mach doch drawDot zu einer Member-Funktion von Console .



  • Ja, ich glaube, so etwas hatten wir schon 😉 siehe Thread https://www.c-plusplus.net/forum/344164 'Basisklasse erstellen?'

    Dort hatte ich mich aber ziemlich verzettelt, denn ich müsste dann doch auch die Klassen Draw und Paint zu Memberklassen von Console machen?



  • Was hat Member-Funktion mit Basisklasse oder Memberklasse zu tun? Ich vermute, du hast die Terminologie nicht ganz verstanden.



  • Das kann gut möglich sein, deshalb versuche ich auch möglichst Begriffe zu umschreiben, wenn ich mir nicht sicher bin. Weiß wie nervend das ist, wenn man jemand nicht helfen kann, weil man nicht weiß wovon er überhaupt spricht.

    Unter Memberfunktion verstehe ich eine Funktion innerhalb der Klasse. Auf Console bezogen würde drawDot() also so aussehen?:

    void Console::drawDot( /*Console& console,*/
                           const Draw& draw, //wie bringe ich Draw dort unter?
                           int X1, int Y1,
                           std::string ch_name, //ist
                           std::size_t ch_idx,  //ne map
                           const bool& show )
    {
        bufferDrawDot( /*console,*/
                       draw,
                       X1, Y1,
                       ch_name, ch_idx,
                       show );
    }
    

    Aufgerufen würde sie mit console.drawDot( draw, x, y, color ); Meintest Du das so?



  • Kleine Anmerkung zum Schluss:

    Ist wohl nicht möglich, innerhalb eines Prozess eine weitere Konsole zu starten. Man kann wohl einen zweiten Prozess starten und dort dann wieder eine Konsole erstellen und über Pipeline oder so kommunizieren. Ist aber Zukunft für mich.

    Ich kann zwar von meiner Console mehrere Instanzen erstellen, es wird aber immer nur eine Konsole gezeigt, die zuletzt, egal in welcher Instanz, erstellt wurde. Dann kann ich zwar die Werte einer Instanz anzeigen lassen, aber die gezeigte Konsole muss mit diesen nicht zu tun haben. Irritiert also eher.

    Es ist also überhaupt nicht notwendig bzw so einfach machbar, verschiedene Console -Objekte zu haben.

    Allerdings ist es gut machbar von meinen Draw - und Paint -Klassen mehrere Instanzen zu erstellen. Zwar dann nur in einer Konsole, aber man gut zwischen den Instanzen wechseln. Ob ich dies sinnbringend einsetzen kann, weiß ich noch nicht.

    Danke fürs lesen 😉


Log in to reply