Zwei Klassen - Datenübernahme



  • Hallo, jetzt habe ich mich hier irgendwie verzettelt. Ich bekomme es nicht hin, das eine Klasse einige Werte einer anderen übernimmt.

    Nochmal meine erste Klasse:

    #define _WIN32_WINNT 0x0500
    #include "display.h"
    #include <vector>
    
    class Console
    {
    
    public:
    
        Display display; //Monitorauflösung holen
        std::vector <CHAR_INFO> outbuffer;
    
        Console() { resize( 800 ); } //Konstruktor
    
        void resize( unsigned int cwindow_size )
        {
            window_size = cwindow_size;
            moveWindow();
            resizeBuffer();
        }
    
         void move( int cpos_x, int cpos_y )
        {
            pos_x = cpos_x;
            pos_y = cpos_y;
            moveWindow();
        }
    
        int getWindowSize() const { return window_size; };
        int getWindowPosX() const { return pos_x; };
        int getWindowPosY() const { return pos_y; };
        double getAspectX() const { return aspect_x; };
        double getAspectY() const { return aspect_y; };
        double getAspectRatio() const { return aspect_ratio; };
        int getColumns() const { return columns; };
        int getRows() const { return rows; };
    
    private:
    
        HANDLE hndl = GetStdHandle( STD_OUTPUT_HANDLE );
        HWND consl = GetConsoleWindow();
        CONSOLE_SCREEN_BUFFER_INFO csbi = {};
    
        unsigned int window_size = 0;
        double aspect_x = 4.0, aspect_y = 3.0;
        double aspect_ratio = aspect_x / aspect_y;
        int pos_x = 0, pos_y = 0;
        int columns = 0, rows = 0;
    
        void getCsbi()
        {
            GetConsoleScreenBufferInfo( hndl, &csbi );
            columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
            rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
        };
    
        void moveWindow()
        {
            if ( window_size < static_cast<unsigned int> ( (display.getHeight() - 22) * aspect_ratio ) ) //wenn window_size einen bestimmten Wert...
            {
                int window_left = static_cast<int> ( (display.getWidth()/2 - window_size/2) ) + pos_x;
                int window_top = static_cast<int> ( (display.getHeight()/2 - (window_size/aspect_ratio)/2) ) + pos_y;
                int window_right = window_size;
                int window_bottom = static_cast<int> ( window_size/aspect_ratio );
                MoveWindow( consl, window_left, window_top, window_right, window_bottom, TRUE );
                getCsbi();
            }
            else //...Konsole wird maximiert
            {
                window_size = display.getWidth();
                pos_x = 0;
                pos_y = 0;
                aspect_x = display.getAspectX();
                aspect_y = display.getAspectY();
                aspect_ratio = aspect_x / aspect_y;
                ShowWindow( consl, SW_MAXIMIZE );
                getCsbi();
            }
        };
    
        void resizeBuffer()
        {
            CHAR_INFO ch;
            ch.Char.UnicodeChar = ' ';
            ch.Attributes = 0;
            outbuffer.resize( columns * rows, ch );
        };
    
    };
    

    Dann habe ich eine zweite:

    #include "console.h"
    
    class Drawing
    {
        struct CoordCenter
        {
            int cx = 0;
            int cy = 0;
        } center;
    
    public:
    
        Console console;
        std::vector <CHAR_INFO> chars;
    
        Drawing() { getChars(); };
    
        void getCoords()
        {
            //console.resize( cwindow_size );
            //console.move( cpos_x, cpos_y );
            setCoords();
        }
    
        unsigned int getCoordWidth() const { return coord_width; };
        unsigned int getCoordHeight() const { return coord_height; };
        int getCoordCenterX() const { return center.cx; };
        int getCoordCenterY() const { return center.cy; };
    
    private:
    
        unsigned int coord_width = 0;
        unsigned int coord_height = 0;
    
        std::vector <WCHAR> unicodes = { '*', 219 };
        std::vector <WORD> attributes = { 0, 15, 7, 8, 4, 12, 6, 14, 10, 11, 3, 9, 1, 13, 5 };
    
        void setCoords()
        {
            coord_width = console.getColumns();
            coord_height = console.getRows() * 2;
            center.cx = coord_width / 2;
            center.cy = coord_height / 2;
        };
    
        void getChars()
        {
            CHAR_INFO ch;
            for ( auto i : unicodes )
            {
                for ( auto j : attributes )
                {
                    ch.Char.UnicodeChar = i;
                    ch.Attributes = j;
                    chars.push_back( ch );
                }
            }
        };
    
    };
    

    die main

    //#include "console.h"
    #include "drawing.h"
    #include <iostream>
    
    void showConsole( Console& console,
                      Drawing& drawing )
    {
        console.resize( 1200 );
        drawing.getCoords(); 
    }
    
    void showValues( const Display& display,
                     const Console& console,
                     const Drawing& drawing )
    {
        std::cout << "Monitor Width: " << display.getWidth() << "  Monitor Height: " << display.getHeight();
        std::cout << "  Aspect Ratio: " << display.getAspectX() << "/" << display.getAspectY() << '\n';
        std::cout << "Console Width: " << console.getWindowSize()
                  << "  Console Height: " << static_cast<int> ( console.getWindowSize() / console.getAspectRatio() );
        std::cout << "  Aspect Ratio: " << console.getAspectX() << "/" << console.getAspectY() << '\n';
        std::cout << "Console Columns: " << console.getColumns() << "  Console Rows: " << console.getRows() << '\n';
        std::cout << "Coord X: " << drawing.getCoordWidth() << "  Coord Y: " << drawing.getCoordHeight();
        std::cout << "  Center X: " << drawing.getCoordCenterX() << "  Center Y: " << drawing.getCoordCenterY() << '\n';
        std::cout << "Console Outbuffer Size: " << console.outbuffer.size();
        std::cout << "  Drawing Chars Size: " << drawing.chars.size() << '\n';
    }
    
    int main()
    {
    
        Display display;
        Console console;
        Drawing drawing;
    
        showConsole( console, drawing );
        showValues( display, console, drawing );
    
    }
    

    Egal, wie ich es drehe und wende, entweder werden die get-Funktionen aus console oder die aus drawing nicht korrekt angezeigt. Das Fenster wird immer korrekt verschoben, aber wie gesagt, entweder werden die Werte von console oder die von drawing korrekt angezeigt, aber nie beide gleichzeitig?
    Und es sind doch alles Werte, die auch in den Klassen zur Berechnung hergenommen werden, warum funktioniert das Verschieben und Ermitteln der Werte, aber nicht die Anzeige?



  • Hallo,

    deine Benennungen sind schlimm 😞
    Ein void-getter, der einen setter aufruft...zumindest ich kann das nicht lesen.

    Dein Problem hab ich jetzt nicht richtig verstanden, aber ich glaube, dass der
    (public) member 'Console console' in Drawing eines deiner Probleme ist.

    Wie gesagt -keine Ahnung was deine Funktionen machen sollen- aber 'showConsole'
    ändert einmal die lokale Console und einmal wird über den getter die member-Console geändert.



  • Welche Werte werden denn falsch angezeigt?

    Ich würde darauf tippen, dein Problem ist, dass du in moveWindow Werte berechnest um die an MoveWindow zu übergeben und dabei erwartest dass due auch in den member Variabeln gespeichert werden. Aber das musst du schon machen.



  • Ja sorry, mit Bezeichnungen tue ich mich wirklich schwer, da immer was zu wählen, ist fast das anstrengendste für mich. Deshalb frage ich auch so ungerne nach, weil dies immer das erste ist, was bemängelt wird.

    Sinn der Sache soll sein, einmal die Konsole zu verändern und dann darauf aufbauend die entsprechenden KO-Werte zu ermitteln. Es soll aber auch möglich sein, die Werte der Konsole in einer Schleife zu ändern, wobei dann nachfolgend auch die KO-Werte geändert werden.

    Was dann da reinkommt wird entsprechend skaliert. Aber weil die Zeichen in der Konsole nicht annähernd quadratisch sind, kann ich nicht einfach die Spalten und Zeilen der Konsole dafür nehmen.



  • Wenn ich showConsole() zb so aufrufe

    void showConsole( Drawing& drawing )
    {
        //console.resize( 1200 );
        drawing.getCoords( 1200, 0, 0 );
    }
    

    und getCoords() in drawing so,

    void getCoords( unsigned int cwindow_size, int cpos_x, int cpos_y )
        {
            console.resize( cwindow_size );
            console.move( cpos_x, cpos_y );
            setCoords();
        }
    

    werden die KO-Werte korrekt angezeigt, aber nicht die Konsolenwerte. Doch die KO-Werte werden doch durch die Konsolenwerte bestimmt? Wieso werden in der Berechnung andere Werte genommen, als in showValues() angezeigt werden?



  • Du hast zwei Instanzen von Console, einmal in main, einmal in Drawing. In Drawing greifst du auf die Instanz von Drawing zu, die natürlich andere Werte hat, als die in main.

    Aber irgendwie ist dein Design, naja. Normalerweise brauchst du Dinge wie die Fenstergröße und die Position, Aspekt etc. gar nicht zu speichern, sondern rufst sie da ab, wo sie gebraucht werden. Dann hast du auch keine Probleme.



  • dref schrieb:

    Du hast zwei Instanzen von Console, einmal in main, einmal in Drawing. In Drawing greifst du auf die Instanz von Drawing zu, die natürlich andere Werte hat, als die in main.

    Aaha, schonmal ein Hinweis, mal schauen, ob ich damit weiterkomme, danke. edit: Aber wie mache ich Console in Drawing bekannt?

    Aber was meinst Du mit speichern von Fenstergröße und Position etc? Wenn ich die Konsole verändern will, muss es doch diese Werte irgendwo geben?



  • per Referenz, so wie du es ja bei der Funktion 'showConsole' auch schon gemacht hast:

    class Drawing
    {
      Console &console;
    
      Drawing(Console &console) : console(console)
      {
      }
    };
    


  • lemon03 schrieb:

    Aber was meinst Du mit speichern von Fenstergröße und Position etc? Wenn ich die Konsole verändern will, muss es doch diese Werte irgendwo geben?

    Klar gibt es die, das Betriebssystem muss die natürlich selber auch speichern.
    Aber da wäre schon ein mittelgroßes Redesign nötig und zumindest grundlegende Programmierkenntnisse mit der WinAPI.

    Einfacher wäre erstmal TH69s Vorschlag.



  • Achhaje, so hatte ich es ja schon fast einmal, danke 🙂

    Ich wollte dann wohl drawing irgendwie ohne Parameter aufrufen wollen.

    Drawing( Console& console ) : console( console ) {}
    

    Aber dieses Konstrukt scheint auch wichtig zu sein. Habe es schon oft gesehen, aber was bewirkt es eigentlich? Und sollte das Referenz-Symbol nicht hinter beim Typ stehen?



  • Die Zuweisung hinter dem Doppelpunkt nennt sich Initialisierungsliste.

    Und wo & (bzw. gilt auch für 😉 steht, das kannst du halten wie ein Dachdecker, also auch so

    Console & console
    


  • Achso, das stand ja sogar im Buch, hatte ich aber nicht erkannt.


Log in to reply