Results 1 to 14 of 14

Thread: Why can't I make dynamic_cast work properly?

  1. #1
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    81
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Why can't I make dynamic_cast work properly?

    Hi!

    I'm having problem with using RTTI when compiling with gcc 4.0.2.
    Is there any flags I should use when compiling? (tried -frtti)
    Read somewhere that I should include <typeinfo> in the headers... but in which headers? All headers
    in the project?

    I thought that it was turned in as default. But when I use dynamic_cast it lets me cast to wathever...

    take this for example:
    Qt Code:
    1. class Thing ( base class, polymorphic )
    2.  
    3. class Contour class Polygon ( subclasses of Thing )
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. Thing *thing = new Contour ( );
    2.  
    3. /* This should work */
    4. Contour *con = dynamic_cast<Contour*) ( thing );
    5. if ( con == NULL )
    6. std::cout<<"con==NULL"<<std::endl;
    7.  
    8. /* this should return a NULL pointer */
    9. Polygon *pol = dynamic_cast<Polygon*) ( thing );
    10. if ( pol == NULL )
    11. std::cout<<"pol==NULL"<<std::endl;
    To copy to clipboard, switch view to plain text mode 

    No of the two returned casts are NULL. From what I understand, the second cast should be NULL since I try to cast a Contour to a Polygon.

    This kind of things just makes me sad...
    pir

  2. #2
    Join Date
    Jan 2006
    Location
    Alingsås, Sweden
    Posts
    437
    Thanks
    3
    Thanked 39 Times in 39 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Why can't I make dynamic_cast work properly?

    It is probably something in you class declarations, could you post the headers please.

  3. #3
    Join Date
    Mar 2006
    Posts
    14
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Why can't I make dynamic_cast work properly?

    Hi,

    As far as I can see from you message, the structure is:

    class Thing;

    class Polygon: public Thing;

    class Contour: public Polygon;

    The dynamic_cast of a thing to a Polygon is valid AND the dynamic_cast of a thing to a Contour is valid if the thing is originally an instance of a Contour. Simply put: a Contour can be seen as a Contour and as a Polygon. So your code is correct, and it is possible that both dynamic_casts result in a non-NULL pointer.

    Hope this helps,
    Beluvius

  4. #4
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    81
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Why can't I make dynamic_cast work properly?

    Hi!

    Here are the headers. There seems like I did a poor job explaining the class tree. So here is the actual tree. The class I called Polygon is actually called PolygonMesh and Contour is called ContourMesh.
    There are two classes in between called Geometrical and Renderable.

    Thing <-- Geometrical <-- Renderable <-- ContourMesh

    Thing <-- Geometrical <-- Renderable <-- PolygonMesh

    The headers of Thing, ContourMesh ( previously called Contour ) and PolygonMesh ( previously called Polygon ) is posted bellow. Since I don't know what you're looing for I've tried to remove as little as possible.

    pir

    Base class Thing:
    Qt Code:
    1. #ifndef THING_HEADERFILE041205
    2. #define THING_HEADERFILE041205
    3.  
    4. #include <iostream>
    5. #include <stdlib.h>
    6. #include <stdio.h>
    7. #include <string>
    8. #include <vector>
    9.  
    10. namespace thing {
    11.  
    12. class Thing {
    13.  
    14. public:
    15.  
    16. Thing ( std::string sName=Thing::sm_sNAME );
    17.  
    18. virtual Thing *copy ( ) const = 0;
    19.  
    20. virtual ~Thing ( );
    21.  
    22. bool operator== ( const Thing& thing ) const;
    23.  
    24. bool static equal ( const Thing &thing1, const Thing &thing2 );
    25.  
    26. friend std::ostream& operator<< ( std::ostream& o,const Thing& thing );
    27.  
    28. virtual Thing* pickout_component ( int id );
    29.  
    30. virtual Thing* get_component ( int id );
    31.  
    32. virtual bool insert_component ( Thing *thing );
    33.  
    34. virtual bool insert_component_at ( Thing *thing, unsigned int pos );
    35.  
    36. virtual bool remove_component_at ( unsigned int pos );
    37.  
    38. void select ( );
    39.  
    40. void unselect ( );
    41.  
    42. bool is_selected ( ) const;
    43.  
    44. bool family_selected ( ) const;
    45.  
    46. const Thing* get_parent ( ) const;
    47.  
    48. Thing* get_parent ( );
    49.  
    50. void set_parent ( Thing* newParent );
    51.  
    52. virtual int size ( ) const;
    53.  
    54. virtual const Thing* at ( int nIndex ) const;
    55.  
    56. virtual Thing* at ( int nIndex );
    57.  
    58. virtual std::vector<Thing*> get_ThingComponents ( );
    59.  
    60. private:
    61.  
    62. static unsigned int sm_nNumCreatedThings;
    63.  
    64. int m_nId;
    65.  
    66. std::string m_sName;
    67.  
    68. bool m_bSaved;
    69.  
    70. bool m_bSelected;
    71.  
    72. Thing *m_tParent;
    73.  
    74. void defaultvalues ( );
    75.  
    76. static const std::string NAME;
    77.  
    78. static const bool SAVED;
    79.  
    80. }; // class Thing
    81.  
    82. }//namespace thing
    83.  
    84. #endif // #ifndef THING_HEADERFILE041205
    To copy to clipboard, switch view to plain text mode 


    Header of ContourMesh:

    Qt Code:
    1. #ifndef CONTOURMESH_HEADERFILE041205
    2. #define CONTOURMESH_HEADERFILE041205
    3.  
    4. #include <vector>
    5. #include <list>
    6. #include "../Renderable/Renderable.h"
    7. #include "./Contour.h"
    8. #include "./contourmeshlib.h"
    9.  
    10. #include "../FORTRAN__/fortran.h"
    11.  
    12. #include <GL/glu.h>
    13.  
    14. namespace contourmesh{
    15.  
    16. class ContourMesh: public renderable::Renderable{
    17.  
    18. public:
    19.  
    20. ContourMesh ( std::string name=sm_sNAME );
    21.  
    22. ContourMesh ( Contour *first, Contour *last, std::string name=sm_sNAME );
    23.  
    24. ContourMesh ( const ContourMesh& contmesh );
    25.  
    26. ContourMesh *copy ( ) const;
    27.  
    28. ~ContourMesh ( );
    29.  
    30. void delete_contours ( );
    31.  
    32. const ContourMesh& operator= ( const ContourMesh& contmesh );
    33.  
    34. friend std::ostream& operator<< ( std::ostream& o, const ContourMesh& cmesh );
    35.  
    36. bool operator== ( const ContourMesh& cmesh ) const;
    37.  
    38. static bool equal ( const ContourMesh& pm1, const ContourMesh& pm2 );
    39.  
    40. Contour* operator[] ( int i );
    41.  
    42. const Contour *operator[] ( int i ) const;
    43.  
    44. static std::vector<ContourMesh*> create_meshes(Contour *firstcontour, Contour *lastcontour);
    45.  
    46. static std::vector<ContourMesh*> divide_mesh(const ContourMesh *cmesh);
    47.  
    48. void copy_creation_data_to(std::vector<ContourMesh*> &pr_vCD) const;
    49.  
    50. void insert_contours(Contour *first, Contour *last);
    51.  
    52. Contour* get_firstcontour ( );
    53.  
    54. int num_contours ( ) const;
    55.  
    56. int num_points ( ) const;
    57.  
    58.  
    59. bool& selectable ( );
    60.  
    61. void draw_shape ( GLfloat pr_fWorldScale=1 );
    62.  
    63. static unsigned int import_into_oneMesh(std::string filename, ContourMesh &cmesh);
    64.  
    65. static void export_ContourMesh(ContourMesh &cmesh, std::string filename);
    66.  
    67. virtual bool
    68. cut ( std::vector<Renderable*> *pr_vInside,
    69. std::vector<Renderable*> *pr_vOutside,
    70. bool pr_bOptimizeEdges, bool pr_bThreeDenvelope,
    71. GLfloat **curve, unsigned int ncurve,
    72. GLfloat pr_fWorldRotationX,
    73. GLfloat pr_fWorldRotationY,
    74. GLfloat pr_fWorldRotationZ,
    75. GLfloat pr_fWorldTranslationX,
    76. GLfloat pr_fWorldTranslationY,
    77. GLfloat pr_fWorldTranslationZ,
    78. GLfloat pr_fWorldScaleX,
    79. GLfloat pr_fWorldScaleY,
    80. GLfloat pr_fWorldScaleZ );
    81.  
    82. void update_boundingbox ( bool bCenterPivots=false );
    83.  
    84.  
    85. protected:
    86.  
    87. std::vector<Contour*> contours;
    88.  
    89. private:
    90.  
    91. const static std::string NAME;
    92.  
    93. static std::string sm_sNAME;
    94.  
    95. static unsigned int sm_nNumCreatedContourMeshes;
    96.  
    97. static bool sm_bClassIsSelectable;
    98.  
    99. void copyContourMesh ( const ContourMesh &cm );
    100.  
    101. void insert_contour ( Contour &contour );
    102.  
    103. static void copy_creation_data ( ContourMesh &to,
    104. const ContourMesh &from );
    105.  
    106. static void check_along ( Contour *tmpcontour, int *along );
    107.  
    108. static void check_thickness ( ContourMesh &cmesh,
    109. float *new_val, float old, int along );
    110.  
    111.  
    112. }; // class ContourMesh
    113.  
    114.  
    115. }// namespace contourmesh
    116. #endif // #ifndef CONTOURMESH_HEADERFILE041205
    To copy to clipboard, switch view to plain text mode 

    header of PolygonMesh:
    Qt Code:
    1. #ifndef POLYGONMESH_HEADERFILE021205
    2. #define POLYGONMESH_HEADERFILE021205
    3.  
    4. #include <stdlib.h>
    5. #include <GL/gl.h>
    6. #include <math.h>
    7. #include <iostream>
    8. #include <list>
    9. #include <vector>
    10. #include <algorithm>
    11.  
    12. #include "../Renderable/Renderable.h"
    13. #include "./polygonmeshlib.h"
    14.  
    15.  
    16. namespace polygonmesh {
    17.  
    18. class PolygonMesh: public renderable::Renderable {
    19. public:
    20.  
    21.  
    22. PolygonMesh ( std::string name = sm_sNAME );
    23.  
    24. PolygonMesh ( unsigned int *P_arr, GLfloat *V_arr, GLfloat *N_arr,
    25. unsigned int numvert, unsigned int numpol,
    26. std::string name = sm_sNAME );
    27.  
    28. PolygonMesh ( const PolygonMesh& pmesh );
    29.  
    30. PolygonMesh *copy ( ) const;
    31.  
    32. ~PolygonMesh ( );
    33.  
    34.  
    35. static std::vector<PolygonMesh*> create_meshes ( GLfloat *vertice_array,
    36. GLfloat *normal_array,
    37. unsigned int *polygon_array,
    38. unsigned int numvertices,
    39. unsigned int numpolygons );
    40.  
    41.  
    42. static std::vector<PolygonMesh*> divide ( PolygonMesh &bigMesh );
    43.  
    44. static PolygonMesh* merge ( const std::vector<PolygonMesh*> &meshes );
    45.  
    46. const PolygonMesh& operator= ( const PolygonMesh& pmesh );
    47.  
    48. friend std::ostream& operator<< ( std::ostream& o, const PolygonMesh& pmesh );
    49.  
    50. bool operator== ( const PolygonMesh& pmesh ) const;
    51.  
    52. static bool equal ( const PolygonMesh& pm1, const PolygonMesh& pm2 );
    53.  
    54. void draw_shape ( GLfloat pr_fWorldScale=1 );
    55.  
    56. void copy_creation_data_to ( std::vector<PolygonMesh*> pr_vMD ) const;
    57.  
    58. GLfloat* get_vertice_array ( );
    59.  
    60. const GLfloat* get_vertice_array ( ) const;
    61.  
    62. void set_vertice_array ( GLfloat *newarray );
    63.  
    64. GLfloat* get_normal_array ( );
    65.  
    66. const GLfloat* get_normal_array ( ) const;
    67.  
    68. void set_normal_array ( GLfloat *narr );
    69.  
    70. bool* get_visible_array ( );
    71.  
    72. const bool* get_visible_array ( ) const;
    73.  
    74. void set_visible_array ( bool *varr );
    75.  
    76. unsigned int* get_polygon_array ( );
    77.  
    78. const unsigned int* get_polygon_array ( ) const;
    79.  
    80. void set_polygon_array ( unsigned int *narr );
    81.  
    82. unsigned int get_number_of_vertices ( ) const;
    83.  
    84. unsigned int& get_number_of_vertices ( );
    85.  
    86. unsigned int get_number_of_polygons ( ) const;
    87.  
    88. unsigned int& get_number_of_polygons ( );
    89.  
    90. float& get_average ( );
    91.  
    92. float get_average ( ) const;
    93.  
    94. float& get_rms ( );
    95.  
    96. float get_rms ( ) const;
    97.  
    98. float& get_sigma ( );
    99.  
    100. float get_sigma ( ) const;
    101.  
    102. float& get_threshold ( );
    103.  
    104. float get_threshold ( ) const;
    105.  
    106. float& get_scale_factor ( );
    107.  
    108. float get_scale_factor ( ) const;
    109.  
    110. int& get_sourceid ( );
    111.  
    112. int get_sourceid ( ) const;
    113.  
    114. std::string& get_filename ( );
    115.  
    116. std::string get_filename ( ) const;
    117.  
    118. bool& selectable ( );
    119.  
    120. bool selectable ( ) const;
    121.  
    122. void update_boundingbox ( bool bCenterPivots=false );
    123.  
    124.  
    125. protected:
    126.  
    127. GLfloat *vertice_array;
    128.  
    129. GLfloat *normal_array;
    130.  
    131. bool *visible_array;
    132.  
    133. unsigned int *polygon_array;
    134.  
    135. unsigned int number_of_vertices;
    136.  
    137. unsigned int number_of_polygons;
    138.  
    139.  
    140. private:
    141.  
    142. float average;
    143.  
    144. float rms;
    145.  
    146. float sigma;
    147.  
    148. float threshold;
    149.  
    150. float scale_factor;
    151.  
    152. int sourceid;
    153.  
    154. std::string filename;
    155.  
    156. static bool sm_bClassIsSelectable;
    157.  
    158. const static std::string NAME;
    159.  
    160. static std::string sm_sNAME;
    161.  
    162. static unsigned int sm_nNumCreatedPolygonMeshes;
    163.  
    164. void copyPolygonMesh ( const PolygonMesh& pmesh );
    165.  
    166. void zerodefaults ( );
    167.  
    168. void init_arrays ( int nvertices, int npolygons );
    169.  
    170. static void copy_creation_data ( PolygonMesh &to, const PolygonMesh &from );
    171.  
    172. };// class PolygonMesh
    173.  
    174.  
    175. }// namespace polygonmesh
    176.  
    177. #endif //#ifndef POLYGONMESH_HEADERFILE041205
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Thanks
    5
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Why can't I make dynamic_cast work properly?

    Your code seems OK.

    Where is the code that fails?
    A camel can go 14 days without drink,
    I can't!!!

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

    Default Re: Why can't I make dynamic_cast work properly?

    You might want to try with some simpler code to see if it works at all:

    Qt Code:
    1. #include <iostream>
    2. class Base {
    3. public:
    4. Base(){}
    5. virtual ~Base(){}
    6. };
    7. class Subclass : public Base {
    8. public:
    9. Subclass():Base(){}
    10. ~Subclass(){}
    11. };
    12. class SubSubclass : public Subclass {
    13. public:
    14. SubSubclass():Subclass(){}
    15. ~SubSubclass(){}
    16. };
    17. class OtherSubclass : public Base {
    18. public:
    19. OtherSubclass():Base(){}
    20. ~OtherSubclass(){}
    21. };
    22.  
    23. int main(){
    24. Base *o = new SubSubclass();
    25. OtherSubclass *test1 = dynamic_cast<OtherSubclass*>(o);
    26. Subclass *test2 = dynamic_cast<Subclass*>(o);
    27. if(test1) std::cout << "Test 1 failed" << std::endl;
    28. if(!test2) std::cout << "Test 2 failed" << std::endl;
    29. if(!test1 && test2) std::cout << "Dynamic cast ok" << std::endl;
    30. return 0;
    31. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    81
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Why can't I make dynamic_cast work properly?

    You're right, its seems like the dynamic_cast is working... when I ran the test program above it printed : Test1 failed. So both casts makes produce a pointer which is not NULL.

    Do I need to turn on rtti? If I do, which flag should I use and do I need to compile all code with this flag?
    I tried a flag called -frtti ( I think it was called that ).

    What should I do now? I have looked at gnus gcc/g++ manual website. But it would be a lie to say that their manuals are the answers to every problem...

    pir

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

    Default Re: Why can't I make dynamic_cast work properly?

    To be honest I just typed "g++ main.cpp -o test" to compile it and it passed both tests.

    Here is my "g++ -v":
    Using built-in specs.
    Target: i586-mandriva-linux-gnu
    Configured with: ../configure --prefix=/usr --libexecdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable-languages=c,c++,ada,f95,objc,java --host=i586-mandriva-linux-gnu --with-system-zlib --enable-long-long --enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions --enable-java-awt=gtk --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --enable-gtk-cairo --disable-libjava-multilib
    Thread model: posix
    gcc version 4.0.1 (4.0.1-5mdk for Mandriva Linux release 2006.0)

  9. #9
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    81
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Why can't I make dynamic_cast work properly?

    Ok, my bad.
    I used the same Makefile as for my project before. When I tried "g++ -o main.cpp test" it turned out ok. So the compiler is ok.

    Here's the flags I use in my Makefile:
    CXXFLAGS = -g -Wall -O0

    Does those cause any problems?

    I have some FORTRAN code in the project as well. I suppose I have to try to take it away. But is there somebody who know if the extern "C" trick turns dynamic_cast into a pile of shit? I use that to make C++ and FORTRAN to comunicate.

    pir

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

    Default Re: Why can't I make dynamic_cast work properly?

    No, it should only affect bindings. *SHOULD*

  11. #11
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    81
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Why can't I make dynamic_cast work properly?

    Ok I found the problem... but not solved it.

    The dynamic_cast doesn't work because I use FORTRAN libs when linking the library. There is one lib called -lcxa that mess dynamic_cast up. Anyone have any tips? The fortran compiler is a Intel 9.0.

    I love FORTRAN, From Out Rectum Taken Rigmarole And Nogood

    pir

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

    Default Re: Why can't I make dynamic_cast work properly?

    Why don't you use gcc to compile your fortran gizmos? AFAIK gcc supports fortran. Maybe it'll work better.

  13. #13
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    81
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Why can't I make dynamic_cast work properly?

    The FORTRAN code is written for the intel ifort compiler. I don't know much about FORTRAN, but there seems like the syntax for ifort FORTRAN is some kind of mix of FORTRAN90 and FORTRAN75 ( or what they are called )... anyway I don't think that it will compile on any other compiler than on ifort.

    But fortunatelly typeid() works just fine, so I can use that in combination with static_cast... Will work for the moment. But I suppose I need to fix this.


    thanks
    pir

  14. #14
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    81
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Why can't I make dynamic_cast work properly?

    If there is someone who cares about this problem... here is the solution.

    check out the link:
    http://yolinux.com/TUTORIALS/LinuxTu...rtranAndC.html

    This is the part that could save a poor (SA)FORTRAN cursed soul some tears:

    Use GNU g++ or Intel C++ compiler to compile and link with main():
    g++ -o name-of-exe main_prog.cpp file1.o file2.o -L/opt/intel/fc/9.0/lib -lifport -lifcore -limf -Wabi -Wcast-align

    If this can help only one person who has this problem, I'm more than happy.
    Last edited by pir; 18th July 2006 at 16:26.

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.