Falsche Variablenwerte bei abgeleiteter Klasse



  • kann man überhaupt in einen Vector für eine klasse objekte einer abgeleiteten klasse speichern? die funktion der abgeleiteten klasse wird nach dem cast zumindest aufgerufen, aber die verfluchten variablen haben falsche werte.



  • der einzige konstruktor enthält zum beispiel das

    ScrollBar::ScrollBar(DWORD orientation, int x, int y, int w, int h, HWND hWndParent, HINSTANCE hInstance )
    {
        init(NULL, "SCROLLBAR", "default", orientation|WS_CHILD|WS_VISIBLE, x,y,w,h,hWndParent, NULL, hInstance, NULL);
        this->scrollStep=1;
        cons<<"ScrollStep after setting to 1: "<<this->scrollStep<<"\n";
        cons<<"Creating Scrollbar\n";
    
    }
    

    Wo?

    Du änderst diesen Wert nur in der init() Methode und die rufst du hier

    case WM_VSCROLL:
                {
                    cons<<"WM_HSCROLL oder WM_HSCROLL\n";
                WinWrap* scroller=mainWindow.searchChild((HWND)lParam);
                if(!scroller)
                    break;
                cons<<"????????___"<<((ScrollBar*)scroller)->asdf<<"\n";        
                cons<<"????????___"<<((ScrollBar*)scroller)->scrollRange<<"\n";     
    
                ((ScrollBar*)scroller)->defaultProc(wParam);
    
                          sprintf(strPosition, "%d", CurPos);
                     SetDlgItemText(hWnd, IDC_LABEL, strPosition);
                return 0;
                }
    

    doch gar nicht auf 😕
    Oder stammt der Code, den du gepostet hast nicht von dieser Stelle?



  • Der Tobi schrieb:

    der einzige konstruktor enthält zum beispiel das

    ScrollBar::ScrollBar(DWORD orientation, int x, int y, int w, int h, HWND hWndParent, HINSTANCE hInstance )
    {
        init(NULL, "SCROLLBAR", "default", orientation|WS_CHILD|WS_VISIBLE, x,y,w,h,hWndParent, NULL, hInstance, NULL);
        this->scrollStep=1;
        cons<<"ScrollStep after setting to 1: "<<this->scrollStep<<"\n";
        cons<<"Creating Scrollbar\n";
     
    }
    

    Wo?

    Du änderst diesen Wert nur in der init() Methode und die rufst du hier

    case WM_VSCROLL:
                {
                    cons<<"WM_HSCROLL oder WM_HSCROLL\n";
                WinWrap* scroller=mainWindow.searchChild((HWND)lParam);
                if(!scroller)
                    break;
                cons<<"????????___"<<((ScrollBar*)scroller)->asdf<<"\n";        
                cons<<"????????___"<<((ScrollBar*)scroller)->scrollRange<<"\n";     
     
                ((ScrollBar*)scroller)->defaultProc(wParam);
                    
     
                          sprintf(strPosition, "%d", CurPos);
                     SetDlgItemText(hWnd, IDC_LABEL, strPosition);
                return 0;
                }
    

    doch gar nicht auf 😕
    Oder stammt der Code, den du gepostet hast nicht von dieser Stelle?

    das im startpost ist abgeändert als beispiel, aber jede variable der abgeleiteten klasse wird nach dem scheiß cast falsch ausgegeben.



  • Deine searchChild-Methode gibt ein WinWrap* zurück. Du weist diesen Rückgabewert einen WinWrap* zurück. Wo zur Hölle sollen die Informationen für den Compiler herkommen, dass du eigentlich ein ScrollBar* haben wolltest? Der fügt die bei dem Cast doch nicht einfach so dazu. Allgemein deuten Casts an, dass du nie ein richtig gutes C++ Buch gelesen hast, denn dort wäre dir die Unnötigkeit von Casts erläutert worden.

    tl;dr: WinWrap* scroller wird ein WinWrap* zugewiesen und du versuchst mit dem Cast einfach nur Compilererrors zu unterdrücken.

    PS: Mach dir um Sone keine Gedanken, er will nur Aufmerksamkeit.



  • wenn c++ primer kein gutes buch ist dann nein, ich hab nie ein gutes c++ buch gelesen.
    ich dachte ein pointer wär immer gleich, egal ob es ein int pointer ist oder ein pointer zu irgendeinem objekt, ist das nicht immer nur ein int wert? oder liegt das am vector objekt wo das zeug gespeichert ist?

    ich hab hier die sache an nem beispiel getestet:

    testclass t01=testclass();
    		testclass02 t02=testclass02();
    
    		testclass* pt01=&t02;
    
    		cout<<"t01: a="<<t01.a<<endl;
    		cout<<"t02: a="<<t02.a<<" b="<<t02.b<<endl;
    
    		cout<<"pointers...."<<endl;
    
    		cout<<((testclass02*)pt01)->b<<endl;
    

    und es funktioniert so mit cast. testclass hat ne variable namens a, testclass02 eine namens b. dem pointer auf testclass wird aber die adresse vom testclass02 objekt zugewiesen, und dann durch nen cast die variable b die nur in testclass02 vorhanden ist ausgegeben. die ausgabe ist immer richtig.



  • Nikolai schrieb:

    ch dachte ein pointer wär immer gleich, egal ob es ein int pointer ist oder ein pointer zu irgendeinem objekt, ist das nicht immer nur ein int wert?

    Na klar. Ein Pointer ist nur ein ganz normaler integraler Basisdatentyp, die Größe ist meistens 4 oder 8 Byte.
    Grob betrachtet können Pointer eben nur eine Adresse speichern.

    Aber diese "Gleichheit" hört schon da auf, wo man die Pointer benutzt.

    Nikolai schrieb:

    oder liegt das am vector objekt wo das zeug gespeichert ist?

    Wie meinst du das? std::vector selbst kann natürlich nicht beeinflussen, wo das Array liegt, den der Standardallokator soll laut Standard ausdrücklich den ganz normalen new -Operator verwenden.

    Nikolai schrieb:

    ich hab hier die sache an nem beispiel getestet:

    testclass t01=testclass();
    		testclass02 t02=testclass02();
    
    		testclass* pt01=&t02;
    		
    		cout<<"t01: a="<<t01.a<<endl;
    		cout<<"t02: a="<<t02.a<<" b="<<t02.b<<endl;
    	
    		cout<<"pointers...."<<endl;
    
    		cout<<((testclass02*)pt01)->b<<endl;
    

    und es funktioniert so mit cast. testclass hat ne variable namens a, testclass02 eine namens b. dem pointer auf testclass wird aber die adresse vom testclass02 objekt zugewiesen, und dann durch nen cast die variable b die nur in testclass02 vorhanden ist ausgegeben. die ausgabe ist immer richtig.

    Na ob das mal nicht UB ist...
    Aber klar, der Offset der Member ist in beiden Klassen natürlich gleich, dann funktioniert es (kannst es ja auch nochmal mit offsetof testen).



  • also ich hab jetzt in der winwrap klase den typ den std::vector speichert in pointer geändert, dadurch funktioniert auch der cast in einen pointer zu einem objekt der abgeleiteten klasse, und die verfluchte scrollbar geht jetzt auch endlich. so wie das voran geht wird bei mir nie ein programm fertig außer konsolenanwendung mit par dialogen.



  • Hallo Nikolai,

    vector<WinWrap> children;
    

    speichert nur die Informationen der Basisklasse - das Stichwort dazu lautet "Slicing", s. z.B. http://en.wikipedia.org/wiki/Object_slicing

    Verwende aber anstatt einem Zeiger besser einen Shared-Pointer z.B. "unique_ptr" oder "shared_ptr" aus C++11 bzw. boost:

    vector<unique_ptr<WinWrap>> children;
    


  • Wenn Boost, wieso dann nicht gleich Pointer-Container?



  • Ich mag diese Pointer Container Library nicht, weil sie intern immer noch "void " anstatt "T" verwendet...
    Und zum anderen, weil ich das Konzept sowie die Benennung "ptr_vector", "ptr_map", ... total bescheuert finde.
    Aber kann ja jeder halten, wie er will...


Anmelden zum Antworten