Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Class Promotion ?



  • Hi Qt Community ,

    The answer i'm afraid can be very obvious , but code-safety is priority .

    I have a class A , inherited by a class B.

    In a certain state , i want my class A to "promote" to class B .
    In other terms , i want the class A to "turn" into a class B that holds all the values of class A , and when i say "turn into" , i mean i want for the events that were occuring to the first instance of class A to still happen to the promoted class B.

    Thanks you very much.



  • I didn't get it. Also I don't get how this is related to Qt.


  • Lifetime Qt Champion

    Hi
    You have
    class B;
    class A : public B

    so A is always a B. ??

    so I dont get it either. :)

    besides it does remind me of
    http://stackoverflow.com/questions/274626/what-is-object-slicing



  • @mrjj

    It's actually :

    class A;

    class B : public A

    Class A has key and mouse events , and multiple protected variables.
    I want from my instance of class A to turn into a class B that contains copies of the values of the variables of class A while keeping the events working .

    Thanks for your help , imma take a look at your link



  • @Wieland

    To be more precise , both my classes A and B are subclassed QGraphicsItem ,
    they only differ in the implementation of the virtual paint() method .


  • Lifetime Qt Champion

    @Walux
    so if u had both paint functions in same class and switched
    at some point, it would be A or B then?
    So if only diff is painting, then if u can switch painting, all be ok ?



  • @mrjj

    It would be in B's shape.

    @mrjj said:

    So if only diff is painting, then if u can switch painting, all be ok ?

    I thought about it , but i'm planning on making more derived classes that'll hold new variables.

    That 'switch' u mentionned is what i'm struggling to do.


  • Lifetime Qt Champion

    @Walux
    the simple version is
    class Master
    all variables..

    class A : Master
    paintEvent

    class B : Master
    paintEvent

    the more lame is
    class A :B
    PaintAsA(QPainter *)
    PaintAsB(QPainter *)

    paintevent(...)
    if(UseB)
    PaintAsB
    else
    PaintAsA

    which is bad with more sublasses



  • Why do your shapes of class A and B have to be related at all? When ever you have an object of A on your scene and you want to "turn it into" an object of B, just create a new object of B, copy the relevant data from A to B and destroy the original A object.



  • @Wieland

    By doing that , i lose all the key and mouse events that happen to class A.



  • You mean events that have been sent to A but haven't been "delivered" to it yet?



  • Yes , how can i assign all of them to the new class B ?



  • Call QCoreApplication::processEvents before destroying A.



  • @mrjj

    Maybe i should do this instead :

    I start by creating a class B that uses the paintEvent of class A , then when i reach the certain state , it calls the paintEvent of class B .

    I have no problem doing it now , since the difference is only in the painting , but later when the new classes have new variables , that'll be a problem .



  • @Wieland

    Maybe a small piece of code will help me understand better , and thank you :)



  • I'm sure the answer i'm looking for lays somewhere between :

    • dynamic_cast
    • virtual
    • operator=

  • Lifetime Qt Champion

    I dont understand why it ever need to change "type".
    I think you need to rethink the design.
    Normally u use base class pointers and childs for polymorph operations but
    i cannot understand your use case.

    Its like circle that must sudden draw as a rect?



  • @mrjj
    @Wieland

    I'll try to minimize the code , to help clarify my situation :

    Class myScene : public QGraphicsScene
    {
    //...
    void MousePressEvent(QGraphicsSceneMouseEvent *event)
    //...
    private:
    A *a;
    //...
    }
    

    "myScene.cpp"

    myScene::myScene 
    {
    a = new A;
    }
    
    void  myScene::MousePressEvent(QGraphicsSceneMouseEvent *event)
    {
    a->doesSmth();
    if(a->reachesSomePoint())
    a = new B;   // Compiles good but i lose the events and the whole paint of a;
    }
    
    Class A : public QObject , public QGraphicsItem
    {
    //...
        A();
        QRectF boundingRect() const Q_DECL_OVERRIDE;
        QPainterPath shape() const Q_DECL_OVERRIDE;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                   QWidget *widget) Q_DECL_OVERRIDE; // This is the first painting
    
        
    //...
          protected:
    qreal myValue1;
    int myValue2;
    //...
    }
    
    Class B : public Class A
    {
            void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                   QWidget *widget) Q_DECL_OVERRIDE; // This is the second painting
    //Future Variables
           private:
    qreal futureValue1;
    //...
    }
    

  • Lifetime Qt Champion

    hi
    You only need to go from base to child?
    You can use a cast for that.
    http://www.bogotobogo.com/cplusplus/upcasting_downcasting.php

    and you dont lose A paint as you are free to call the A::paintEvent from
    B::paintEvent.



  • @mrjj

    Thanks for your help , glad you stayed with me till the bottom ;)
    Imma read the content of your link :)



  • Hmm , very informative , and i can get the slicing problem now :)
    But , it won't be of any harm till late versions of my program :)
    Thank you very much :D

    Topic->setAsSloved(true);


  • Lifetime Qt Champion

    @Walux
    Np.
    Its not always you run into slicing but its good to know it can happen.


Log in to reply