Results 1 to 14 of 14

Thread: Can I cast a pointer from a unknow type ?

  1. #1
    Join Date
    Aug 2008
    Location
    Algarve, Portugal
    Posts
    288
    Thanks
    23
    Thanked 32 Times in 28 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Can I cast a pointer from a unknow type ?

    I have a list of pointers that can be from diferent derived classes of BaseClass. I want to duplicate some items who's indexes are in m_listEntities_selected (a list of type int). newPosition() is a virtual member. Can I cast 'entity', since I don't know the type of the item at the specified position?

    Qt Code:
    1. for(int i=0;i<m_listEntities_selected.size();i++)
    2. {
    3. BaseClass *entity = new BaseClass;
    4. entity = dynamic_cast< typeid (m_listEntities.at(m_listEntities_selected[i]) ) > (m_listEntities.at(m_listEntities_selected.at(i))); // this is the error
    5. *entity = *m_listEntities.at(m_listEntities_selected.at(i) );
    6. entity->newPosition(point3d-point_base_copy);
    7. m_listEntities.append(entity);
    8. }
    To copy to clipboard, switch view to plain text mode 

    I can solve my problem with a switch case, because I have virtual members in the derived classes that give a string with the type but that will be much less elegant and I will have to modify the switch case every time I create a new derived class. Any sugestion ?
    __________________________________________________
    My projects: calculator MathGraphica ; SuperEpicMegaHero game ; GooglePlay ; bitbucket ; github
    Like my projects ? Buy me a kofi

  2. #2
    Join Date
    Apr 2011
    Posts
    124
    Thanks
    1
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows Symbian S60

    Default Re: Can I cast a pointer from a unknow type ?

    1) Why do you assign a new BaseClass to entity and then in the next line assign something else to entity? Doesn't that just leak a BaseClass for no good purpose?

    2) What is the point in casting something to the type that it is? What does it achieve?

    3) If line 4 succeeded, wouldn't line 5 just be assigning a value to itself?
    Last edited by DanH; 25th May 2011 at 04:19.

  3. #3
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Can I cast a pointer from a unknow type ?

    May be you want to do it this way
    Qt Code:
    1. ...
    2. //This will the factory method to create the derived class objects
    3. BaseClass *createDerivedClass(int class_index)
    4. {
    5. BaseClass *entity;
    6. ...
    7. //create a new derived class based on the class_index / new_entity
    8. ...
    9. return entity;
    10. }
    11.  
    12. ...
    13. for(int i=0;i<m_listEntities_selected.size();i++)
    14. {
    15. BaseClass *new_entity = m_listEntities.at(m_listEntities_selected.at(i));
    16. BaseClass *entity = createDerivedClass(m_listEntities_selected.at(i));
    17.  
    18. //BaseClass *entity = createDerivedClass(new_entity); //this can also be a way, instead on index
    19. //in the factory method know the type of new_entity, and return a new object of same type
    20.  
    21. // duplicate or so
    22. *entity = *new_entity;
    23.  
    24. entity->newPosition(point3d-point_base_copy);
    25. m_listEntities.append(entity);
    26. }
    27. ...
    To copy to clipboard, switch view to plain text mode 
    Last edited by Santosh Reddy; 25th May 2011 at 07:04. Reason: updated contents

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Can I cast a pointer from a unknow type ?

    What you want is polymorphism.
    Google it, its a basic C++ concept, once you have understood it, your question will be answered.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Aug 2008
    Location
    Algarve, Portugal
    Posts
    288
    Thanks
    23
    Thanked 32 Times in 28 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Re: Can I cast a pointer from a unknow type ?

    @Santosh Reddy: That exactly what I want to do.
    @high_flyer: I now about polymorphism, I thing you didnt understand my question
    @ DanH: I will explain better, I have a QList of pointers to a base class:

    Qt Code:
    1. class Baseclass
    2. {
    3. virtual void draw(){};
    4. virtual QString type() const{return "base";}
    5. }
    6.  
    7. class Entity_Lines : public Baseclass
    8. {
    9. void draw();
    10. QString type() const{return "Line";}
    11. }
    12.  
    13. class Entity_PolyLines : public Baseclass
    14. {
    15. void draw();
    16. QString type() const{return "polyline";}
    17. }
    18.  
    19. QList<Baseclass *> m_listEntities;
    To copy to clipboard, switch view to plain text mode 

    That list will be filled with lines and polylines from derived classes.

    At run time I want to copy some given elements from m_listEntities and append them to m_listEntities (this is when the user creates new lines/polylines from existent selected ones)
    I solved my problem, it's working with the following code:

    Qt Code:
    1. for(int i=0;i<m_listEntities_selected.size();i++)
    2. {
    3. if ( m_listEntities.at(m_listEntities_selected.at(i))->type() == "Line" )
    4. {
    5. Entity_Lines *entity = new Entity_Lines;
    6. *entity = *dynamic_cast<Entity_Lines*> (m_listEntities.at(m_listEntities_selected.at(i)) );
    7. entity->newPosition(point3d-point_base_copy);
    8. m_listEntities.append(entity);
    9.  
    10. }
    11. else if ( m_listEntities.at(m_listEntities_selected.at(i))->type() == "polyline" )
    12. {
    13. Entity_PolyLines *entity = new Entity_PolyLines;
    14. *entity = *dynamic_cast<Entity_PolyLines*> (m_listEntities.at(m_listEntities_selected.at(i)) );
    15. entity->newPosition(point3d-point_base_copy);
    16. m_listEntities.append(entity);
    17. }
    18. }
    To copy to clipboard, switch view to plain text mode 

    But is not that elegant since I will have to keep adding new "if else" for every new derived class entities (circles, squares, whatever...)
    I was trying a better generic solution like this

    Qt Code:
    1. for(int i=0;i<m_listEntities_selected.size();i++)
    2. {
    3. Baseclass *entity = new Baseclass;
    4. *entity = *dynamic_cast<(typeid(m_listEntities.at(m_listEntities_selected[i]) ) )> (m_listEntities.at(m_listEntities_selected.at(i)));//errors
    5. entity->newPosition(point3d-point_base_copy);
    6. m_listEntities.append(entity);
    7. }
    To copy to clipboard, switch view to plain text mode 

    Basically I'm trying to do a cast at run time, using typeid to grab the object type, but I get 2 errors:
    Qt Code:
    1. error: expected type-specifier before ‘(’ token
    2. error: expected ‘>’ before ‘(’ token
    To copy to clipboard, switch view to plain text mode 
    __________________________________________________
    My projects: calculator MathGraphica ; SuperEpicMegaHero game ; GooglePlay ; bitbucket ; github
    Like my projects ? Buy me a kofi

  6. #6
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Can I cast a pointer from a unknow type ?

    As high_flyer mentioned, you not very clear in how inheritance in C++ works, (or at-least how to use it, in your case).

    Qt Code:
    1. Baseclass *entity = new Baseclass;
    To copy to clipboard, switch view to plain text mode 
    This is not correct, you should be using new DerivedClass, or a factory method to create object and get it's base class pointer. If you do it this way, you are basically creating a BaseClass Object and store it in BaseClass pointer, where as you want to create a DerivedClass object, and store it in BaseClass pointer.

    *entity = *dynamic_cast<(typeid(m_listEntities.at(m_listEnti ties_selected[i]) ) )> (m_listEntities.at(m_listEntities_selected.at(i))) ;//errors
    This is not possible, you need to know the type at compile time to cast it to, where as typeid operator returns a type_info class object (which happens at runtime), and again which is of type type_info, not your BaseClass (as you expect)

    you can use the typeid operator to get type information like, this

    typeid(int).name()
    typeid(derived).name() //parameter can be object, class, or object pointer..
    if(typeid(object1) == typeid(object2)) //this is run time object creation, and uses the type_info class == operator to compare the objects
    ...
    Conclusion:
    To create a DerivedClass object, you cannot avoid if..else (or switch case), to know the type(or other criteria) to create object. The best practice is either have factory class, or a factory method, which is the solution provided by the factory design pattern for your problem.

    I suggest you reading about factory design pattern, which is cleaner, maintainable (adding new derived classes in future) solution to your problem.

  7. The following user says thank you to Santosh Reddy for this useful post:

    john_god (26th May 2011)

  8. #7
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Can I cast a pointer from a unknow type ?

    @high_flyer: I now about polymorphism, I thing you didnt understand my question
    You maybe know about polymorphism, but it seems you are not so clear on HOW it works, and how it should be used, as the the poster above me said.

    Specifically to your case, since all your derived classes are the same (implement the same methods), you can just use the base class pointer with out even the need to know which derived type is currently occupying it, the code of the derived class will be executed - you don't need the if else sections!

    Also, it looks you don't understand how allocation works:
    Qt Code:
    1. for(int i=0;i<m_listEntities_selected.size();i++)
    2. {
    3. Baseclass *entity = new Baseclass; //<<---you allocate Baseclass, and in the next line you override that pointer, creating a leak!
    4. //and the this line and conversions are totally confused - you extract the 'i' element, convert based on it? and add the new element? what is the sense in that?
    5. *entity = *dynamic_cast<(typeid(m_listEntities.at(m_listEntities_selected[i]) ) )> (m_listEntities.at(m_listEntities_selected.at(i)));//errors
    6. entity->newPosition(point3d-point_base_copy);
    7. m_listEntities.append(entity);
    8. }
    To copy to clipboard, switch view to plain text mode 

    This should be enough:
    Qt Code:
    1. for(int i=0;i<m_listEntities_selected.size();i++)
    2. {
    3. Baseclass *entity = new <Any of the Baseclass derived classes>;
    4. entity->newPosition(point3d-point_base_copy); //this method does not appear in any of your class decelerations?
    5. m_listEntities.append(entity);
    6. }
    7.  
    8. //Then when you use the list entries:
    9. m_listEntities.at(i)->draw(); //the correct draw() will be called since your subclasses implement the virtual draw()!. You don't need to convert anything!
    10. //You would need to convert between the types only when they implement additional methods, not declared in the base class.
    11. //But if all you want is to execute the same methods on the various types, no conversion is needed, this is what polymorphism is for.
    To copy to clipboard, switch view to plain text mode 

    Again, read about polymorphism, until you are really comfortable with how it works!
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  9. #8
    Join Date
    Aug 2008
    Location
    Algarve, Portugal
    Posts
    288
    Thanks
    23
    Thanked 32 Times in 28 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Re: Can I cast a pointer from a unknow type ?

    Baseclass *entity = new Baseclass; //<<---you allocate Baseclass, and in the next line you override that pointer, creating a leak!
    You are right this is a error I have

    //and the this line and conversions are totally confused - you extract the 'i' element, convert based on it? and add the new element? what is the sense in that?
    *entity = *dynamic_cast<(typeid(m_listEntities.at(m_listEnti ties_selected[i]) ) )> (m_listEntities.at(m_listEntities_selected.at(i))) ;//errors
    This is exactly what I want, I'll explain: this is a cad projetc where the user can draw entities (lines, polylines, ...). If the user draws 3 lines and 2 polylines (by this order), m_listEntities will have 5 elements. If the user selects some entities (lets say 1 line and 1 polyline) the indexes of the select entities are stored in QList m_listEntities_selected (wich is if of type int, and it will have 2 elements, the indexes of the selected entities).
    The user can create a copy of the selected entities and move then with the mouse to a new position. The cicle for is looping throw all the select entities, copies them and add them to m_listEntities wich now will have 7 elements.

    entity->newPosition(point3d-point_base_copy); //this method does not appear in any of your class decelerations?
    I've omitted for simplicity sake, I'm sorry if I didnt explain myself better, this is a virtual method in base class and also exists in derived classes. This will update the coordinates of the 2 new entities.

    Baseclass *entity = new <Any of the Baseclass derived classes>;
    This is exactly my problem, I don't know what derived class is, can be a line or polyline, depends from what the user has draw. My question is all about this, how can I now at run time ? The factory method seems good, or a if else or a switch, but if I could use the line I have errors it would be better wich aparently I can't. I admit I not a great C++ expert so I'm calling for help with this post, and I really apreciate your help so far.



    //Then when you use the list entries:
    m_listEntities.at(i)->draw(); //the correct draw() will be called since your subclasses implement the virtual draw()!. You don't need to convert anything!
    //You would need to convert between the types only when they implement additional methods, not declared in the base class.
    //But if all you want is to execute the same methods on the various types, no conversion is needed, this is what polymorphism is for.
    I'm not sure if I understand you correctly.
    I have a QGLWidget wich in the paint event method has a loop that draws the entities, something like

    Qt Code:
    1. for (int i=0;i<m_listEntities->size();i++)
    2. {
    3. m_listEntities.at(i)->draw();
    4. }
    To copy to clipboard, switch view to plain text mode 

    The draw() method of the baseclass is just a empty method, but in the derived class Entity_Lines I've code that draws a line, in Entity_PolyLines it draws polylines. That's the understanding I have about polymorphism.

    Regards
    John
    __________________________________________________
    My projects: calculator MathGraphica ; SuperEpicMegaHero game ; GooglePlay ; bitbucket ; github
    Like my projects ? Buy me a kofi

  10. #9
    Join Date
    Apr 2011
    Posts
    124
    Thanks
    1
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows Symbian S60

    Default Re: Can I cast a pointer from a unknow type ?

    While it probably is technically possible in Qt (I've never tried it) to generate an object of a class starting with the class name as a string, it's much simpler and less error prone to just use a switch statement:
    Qt Code:
    1. BaseClass* theCreatedObject = NULL;
    2. switch (classId) {
    3. case ClassIdLine:
    4. theCreatedObject = new Line();
    5. break;
    6. case ClassIdPolyLine:
    7. theCreatedObject = new PolyLine();
    8. break;
    9. case ....
    10. ....
    11. }
    To copy to clipboard, switch view to plain text mode 

  11. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Can I cast a pointer from a unknow type ?

    Or use the Factory or Builder design pattern.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #11
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Can I cast a pointer from a unknow type ?

    This is exactly what I want, I'll explain: this is a cad projetc where the user can draw entities (lines, polylines, ...). If the user draws 3 lines and 2 polylines (by this order), m_listEntities will have 5 elements. If the user selects some entities (lets say 1 line and 1 polyline) the indexes of the select entities are stored in QList m_listEntities_selected (wich is if of type int, and it will have 2 elements, the indexes of the selected entities).
    The user can create a copy of the selected entities and move then with the mouse to a new position. The cicle for is looping throw all the select entities, copies them and add them to m_listEntities wich now will have 7 elements.
    If you want to copy/paste/move things then you should consider signal & slots for doing so, rather than looping though the entities (which will a performance issue if you have large number of entities).

  13. #12
    Join Date
    Aug 2008
    Location
    Algarve, Portugal
    Posts
    288
    Thanks
    23
    Thanked 32 Times in 28 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Re: Can I cast a pointer from a unknow type ?

    The list of entities can grow up to thousands, depends what the user draws
    I'm not sure how signal slot can improve performance, I'm not looping throw all the list entities, just throw the seleted entities.
    I'll have to think about this
    __________________________________________________
    My projects: calculator MathGraphica ; SuperEpicMegaHero game ; GooglePlay ; bitbucket ; github
    Like my projects ? Buy me a kofi

  14. #13
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Can I cast a pointer from a unknow type ?

    a rather common solution would be to add a (pure) virtual method
    Qt Code:
    1. BaseClass* clone() const;
    To copy to clipboard, switch view to plain text mode 
    to BaseClass. Reimplement it in all its subclasses and just call clone() for all selected items.

  15. #14
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Can I cast a pointer from a unknow type ?

    @OP:
    You have simplest case of what inheritance is there to solve, you are over complicating it big time (probably because you don't grasp yet how and what inheritance does).

    This is exactly what I want, I'll explain: this is a cad projetc where the user can draw entities (lines, polylines, ...). If the user draws 3 lines and 2 polylines (by this order), m_listEntities will have 5 elements. If the user selects some entities (lets say 1 line and 1 polyline) the indexes of the select entities are stored in QList m_listEntities_selected (wich is if of type int, and it will have 2 elements, the indexes of the selected entities).
    The user can create a copy of the selected entities and move then with the mouse to a new position. The cicle for is looping throw all the select entities, copies them and add them to m_listEntities wich now will have 7 elements.
    This can (and should) be solved using OOP.
    You don't need an extra list for the selected entities, all you need is a setSelected() and isSelected() methods in your base entity class.
    Using a list, or better yet a set of the selected entities so that you can save the looping when you search you selected items - then use a set that stores the pointers of the selected entities.
    But information it self, if an item is selected or not should be encapsulated in to the object, not in an external list!

    So:
    Instead of you m_listEntities_selected make a:
    Qt Code:
    1. QSet<BaseClass*> m_setSelectedEnteties;
    To copy to clipboard, switch view to plain text mode 
    There are many ways you can fill this set, one easy way would be that your entities emit a signal when they are selected, and in the slot you just add the address of the sender to the set.
    You do the same for removing the items from the set in a slot connected to a "unselected" signal.
    Now that you have your selected entities, you can do as the poster above me suggested:
    Qt Code:
    1. foreach (BaseClass *pSelectedEntity, m_setSelectedEnteties){
    2. BaseClass *pEntity = pSelectedEntity->clone();
    3. m_listEntities->append(pEntity);
    4. }
    To copy to clipboard, switch view to plain text mode 

    Nice and easy.
    As you can see, thanks to correct usage of inheritance, you don't have to bother with types.
    The specific implementation for each type is encapsulated in the implementation of the virtual method in the various BaseClass subclasses.
    Last edited by high_flyer; 30th May 2011 at 13:05.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  16. The following user says thank you to high_flyer for this useful post:

    john_god (30th May 2011)

Similar Threads

  1. Replies: 1
    Last Post: 4th December 2010, 17:20
  2. Pointer of an unknown type...
    By TheNewGuy in forum Newbie
    Replies: 1
    Last Post: 17th December 2009, 08:50
  3. Dynamic pointer type
    By estanisgeyer in forum General Programming
    Replies: 3
    Last Post: 9th October 2008, 16:51
  4. QFile Problem~ "Unknow error" in "open(QIODevice::ReadWrite)"
    By fengtian.we in forum Qt Programming
    Replies: 3
    Last Post: 23rd May 2007, 15:58
  5. cast
    By mickey in forum General Programming
    Replies: 1
    Last Post: 12th July 2006, 11:10

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.