Strange dynamic_cast problem
-
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
-
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
-
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
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
-
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
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
-
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