Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Strange dynamic_cast problem

Strange dynamic_cast problem

Scheduled Pinned Locked Moved C / C++ / MFC
helpc++oopquestion
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Y Offline
    Y Offline
    yccheok
    wrote on last edited by
    #1

    Hello, I have an object called XXX previously derived from CDocument in my MDI project. Later, I create an concrete class called Subject. And I let XXX to have multiple inheritance from Subject (Subject is an object with protected constructor) The problem is, whenever I used dynamic_cast to cast a Subject pointer to XXX (I am quite sure Subject pointer is actually pointing to XXX), a visual c++ runtime error will occur. void fun(Subject *s) { XXX *var = dynamic_cast(s); var->hehehe(); } However, when I try to do this: void fun(Subject *s) { XXX *var = (XXX *)(s); var->hehehe(); } everything just go fine. may i noe why this happen? is this bug related to something called dynamic creation? thanks you. cheok

    S 1 Reply Last reply
    0
    • Y yccheok

      Hello, I have an object called XXX previously derived from CDocument in my MDI project. Later, I create an concrete class called Subject. And I let XXX to have multiple inheritance from Subject (Subject is an object with protected constructor) The problem is, whenever I used dynamic_cast to cast a Subject pointer to XXX (I am quite sure Subject pointer is actually pointing to XXX), a visual c++ runtime error will occur. void fun(Subject *s) { XXX *var = dynamic_cast(s); var->hehehe(); } However, when I try to do this: void fun(Subject *s) { XXX *var = (XXX *)(s); var->hehehe(); } everything just go fine. may i noe why this happen? is this bug related to something called dynamic creation? thanks you. cheok

      S Offline
      S Offline
      squidev
      wrote on last edited by
      #2

      Hi, Have you tried enabling RTTI for your project ? When it's enabled, instead of throwing an exception, the dynamic_cast will return NULL (make sure you check the return value!:-O) Hope this helps

      Y 1 Reply Last reply
      0
      • S squidev

        Hi, Have you tried enabling RTTI for your project ? When it's enabled, instead of throwing an exception, the dynamic_cast will return NULL (make sure you check the return value!:-O) Hope this helps

        Y Offline
        Y Offline
        yccheok
        wrote on last edited by
        #3

        Can you please let me know how I can enable RTTI for the project? Please note that for the classes which my CDocument inheritance from, I created by hand. Here is my details: I have an abstract class named CObserver and a concrete class named CSubject. The purpose of having this two classes is that, some interesting event will always happen in subject. observer is a guy which is interested in the event in subject. subject will notify all the observers attached to it whenever an event happen. --------------------------------------------------------------------- class CObserver { public: virtual ~CObserver(); virtual void Update(CSubject *s) const=0; protected: CObserver(); }; class CSubject { public: virtual ~CSubject(); virtual void Attach(CObserver *o); virtual void Detach(CObserver *o); virtual void Notify(); protected: CSubject(); private: CList _observers; }; --------------------------------------------------------------------- Now, I need to monitor a IO port. Then, I need to notify my CDocument whenever there is some IO activity. Hence, I create an CIOMonitor class which is single inheritance from CSubject. // Please note that I remove most of the members. Only leave those which is related to this bug class CIOMonitor : public CSubject { int GetInt() const; } I use Wizard in VC++ to create MDI project. Then, for the CCatchbugDoc (multiple inheritance from CDocument and CObserver). This is because CCatchbugDoc will be interested in the event happen in CIOMonitor class CCatchbugDoc : public CDocument, public CObserver { public: virtual void Update(CSubject *s) const; }; Please note here is the root of evil void CCatchbugDoc::Update(CSubject *s) const { /* Everything work fine with this unsafe casting */ /* But dynamic casting just prompt me a runtime error */ /**/ /* CIOMonitor *p = (CIOMonitor *)s; */ CIOMonitor *p = dynamic_cast(s); if(p == NULL) { AfxMessageBox("unknown error during dynamic cast"); return; } CString string; string.Format("Nofity. CIOMonitor: %i", p->GetInt()); AfxMessageBox(string); } Here is my suspection 1. In VC++, CCatchbugDoc is created using dynamic creation. Initially, CCatchbugDoc is single inheritance from CDOcument. The following macro is added by VC++ wizard to enable dynamic creation: IM

        S 1 Reply Last reply
        0
        • Y yccheok

          Can you please let me know how I can enable RTTI for the project? Please note that for the classes which my CDocument inheritance from, I created by hand. Here is my details: I have an abstract class named CObserver and a concrete class named CSubject. The purpose of having this two classes is that, some interesting event will always happen in subject. observer is a guy which is interested in the event in subject. subject will notify all the observers attached to it whenever an event happen. --------------------------------------------------------------------- class CObserver { public: virtual ~CObserver(); virtual void Update(CSubject *s) const=0; protected: CObserver(); }; class CSubject { public: virtual ~CSubject(); virtual void Attach(CObserver *o); virtual void Detach(CObserver *o); virtual void Notify(); protected: CSubject(); private: CList _observers; }; --------------------------------------------------------------------- Now, I need to monitor a IO port. Then, I need to notify my CDocument whenever there is some IO activity. Hence, I create an CIOMonitor class which is single inheritance from CSubject. // Please note that I remove most of the members. Only leave those which is related to this bug class CIOMonitor : public CSubject { int GetInt() const; } I use Wizard in VC++ to create MDI project. Then, for the CCatchbugDoc (multiple inheritance from CDocument and CObserver). This is because CCatchbugDoc will be interested in the event happen in CIOMonitor class CCatchbugDoc : public CDocument, public CObserver { public: virtual void Update(CSubject *s) const; }; Please note here is the root of evil void CCatchbugDoc::Update(CSubject *s) const { /* Everything work fine with this unsafe casting */ /* But dynamic casting just prompt me a runtime error */ /**/ /* CIOMonitor *p = (CIOMonitor *)s; */ CIOMonitor *p = dynamic_cast(s); if(p == NULL) { AfxMessageBox("unknown error during dynamic cast"); return; } CString string; string.Format("Nofity. CIOMonitor: %i", p->GetInt()); AfxMessageBox(string); } Here is my suspection 1. In VC++, CCatchbugDoc is created using dynamic creation. Initially, CCatchbugDoc is single inheritance from CDOcument. The following macro is added by VC++ wizard to enable dynamic creation: IM

          S Offline
          S Offline
          squidev
          wrote on last edited by
          #4

          In VC++ 6.0: Go to Project->Settings... Go to the C/C++ tab Category = C++ Language Check the box "Enable Run-Time Type Information (RTTI) Set this to both Debug and Release This makes your exe slightly bigger (not that much), but it allows you to query the types of the objects you're using, and use dynamic_cast. Watch out for name clashes when using multiple inheritence. If you really need to use this, make sure the base classes do not have methods with the same name (and the base classes' base classes...). Hope this helps

          Y 1 Reply Last reply
          0
          • S squidev

            In VC++ 6.0: Go to Project->Settings... Go to the C/C++ tab Category = C++ Language Check the box "Enable Run-Time Type Information (RTTI) Set this to both Debug and Release This makes your exe slightly bigger (not that much), but it allows you to query the types of the objects you're using, and use dynamic_cast. Watch out for name clashes when using multiple inheritence. If you really need to use this, make sure the base classes do not have methods with the same name (and the base classes' base classes...). Hope this helps

            Y Offline
            Y Offline
            yccheok
            wrote on last edited by
            #5

            Thanks. :) That's really help me out. Just wondering why vc++ doesn't enable RTTI by default. I think they should give us compilation error when it encounter the user is trying to use RTTI feature by not enabling the RTTI flag. :(

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups