MFC macro strangeness with multiple inheritance
Paul.B.Folbrecht@JCI.Com Wednesday, October 16, 1996 Environment: Win95, Visual C++ 4.1 OK, here's a really strange item. The situation: I have a simple, abstract mixin class with a single pure virtual function, as so: class CNotify { public: virtual void OnEvent() = 0; }; I also have a dialog class, multiple derived from both CDialog and CNotify: class CMyDialog : public CDialog, public CNotify From another class, I call the dialog's OnEvent() method, which of course it has defined. What happens? It goes not to OnEvent, but to the IMPLEMENT_DYNAMIC macro, specifically to GetRuntimeClass(), then returns without ever hitting OnEvent. I know MFC can be finicky with multiple inheritance, but there's nothing here that should cause a problem. I'm not completing any diamond which I know is a no-no with MFC. Incidentally, I've tried reversing the order of the base classes in the CMyDialog declaration, and this causes the dialog to fail to work completely, blowing up on creation. I'v tried doing full builds to no avail. -Paul Folbrecht, Compuware Corp.
Mario Contestabile -- Mario_Contestabile.UOS__MTL@UOSMTL2.universal.com Friday, October 18, 1996 [Mini-digest: 3 responses] >From another class, I call the dialog's OnEvent() method, which of > course it has defined. What happens? It goes not to OnEvent, but to > the IMPLEMENT_DYNAMIC macro Why isn't the code snippet for the virtual function call included with the question? mcontest@universal.com -----From: Mike KurtinitisHi Paul, I recently experienced the *exact* problem you've described. I found the solution to lie in the way pointers are casted. My bet is you're doing something like this: CSomeClass theClass; CDialog* pDlg; pDlg = m_pMyDlg; // m_pMyDlg is an instance of CMyDialog theClass.StoreDialog((CNotify*)pDlg); Later on some other code inside CSomeClass does the following: m_pStoredDlg->OnEvent(); // Jumps to the top of the file To remedy this, pass a CMyDialog* instead of a CDialog* to StoreDialog() . The wrong VTABLE is being used to look up the OnNotify() call. By properly casting the pointer you can insure the correct VTABLE is used. I'd be glad to look at the actual snippet of code that is causing you problems if what I described isn't the culprit. Good Luck, -Mike Kurtinitis Mooshwerks moosh@halcyon.com At 08:43 AM 10/16/96 -0600, you wrote: > Environment: Win95, Visual C++ 4.1 > > OK, here's a really strange item. > > The situation: I have a simple, abstract mixin class with a single > pure virtual function, as so: > > class CNotify > { > public: > virtual void OnEvent() = 0; > }; > > I also have a dialog class, multiple derived from both CDialog and > CNotify: > > class CMyDialog : public CDialog, public CNotify > > From another class, I call the dialog's OnEvent() method, which of > course it has defined. What happens? It goes not to OnEvent, but to > the IMPLEMENT_DYNAMIC macro, specifically to GetRuntimeClass(), then > returns without ever hitting OnEvent. > > I know MFC can be finicky with multiple inheritance, but there's > nothing here that should cause a problem. I'm not completing any > diamond which I know is a no-no with MFC. Incidentally, I've tried > reversing the order of the base classes in the CMyDialog declaration, > and this causes the dialog to fail to work completely, blowing up on > creation. I'v tried doing full builds to no avail. > > -Paul Folbrecht, > Compuware Corp. > > -----From: Kostya Sebov You must be using the pattern: void CMyControl::OnSomething() { CNotify* pToBeNotified = (CNotify*)GetParent(); pToBeNoftified->OnEvent(); // here's the trap } You should code: CNotify* pToBeNotified = (CMyDialog*)GetParent(); to allow the compiler correctly resolve pointers to v-tables. HTH --- Kostya Sebov. ---------------------------------------------------------------------------- Tel: (38 044) 266-6387 | Fax: (38 044) 266-6195 | E-mail: sebov@is.kiev.ua
CBYRNEHAM@derwent.co.uk Tuesday, October 22, 1996 [Mini-digest: 3 responses] Environment: Win95, Visual C++ 4.2 You've probably fixed it by now... Its a shame you chose the name OnEvent as thats already defined in CCmdTarget. ( From which CDialog is of course derived ) Did your original OnEvent have some parameters ?? With the no parameter version you describe it compiles and runs O.K. on 4.2 Have you tried using a different function name :) Best regards, Chris Byrneham. -----From: Paul.B.Folbrecht@JCI.Com Yes, I fixed it by changing the direct cast to (CNotify*) I was using to a dynamic_cast. I should've known the direct cast is a no-no when multiple inheritance is involved. Also, OnEvent was not the actual name I was using. -Paul -----From: Paul.B.Folbrecht@JCI.Com To all who replied to this problem: The problem was indeed caused by mismatched vtables. My original call (sorry for not including that) was like this: CNotify* pDlg = (CNotify*) ... Changing the straight cast to dynamic_cast causes the runtime system to supply the correct pointer. -Paul -----From: Mike KurtinitisHi Paul, I recently experienced the *exact* problem you've described. I found the solution to lie in the way pointers are casted. My bet is you're doing something like this: CSomeClass theClass; CDialog* pDlg; pDlg = m_pMyDlg; // m_pMyDlg is an instance of CMyDialog theClass.StoreDialog((CNotify*)pDlg); Later on some other code inside CSomeClass does the following: m_pStoredDlg->OnEvent(); // Jumps to the top of the file To remedy this, pass a CMyDialog* instead of a CDialog* to StoreDialog() . The wrong VTABLE is being used to look up the OnNotify() call. By properly casting the pointer you can insure the correct VTABLE is used. I'd be glad to look at the actual snippet of code that is causing you problems if what I described isn't the culprit. Good Luck, -Mike Kurtinitis Mooshwerks moosh@halcyon.com -----From: Kostya Sebov You must be using the pattern: void CMyControl::OnSomething() { CNotify* pToBeNotified = (CNotify*)GetParent(); pToBeNoftified->OnEvent(); // here's the trap } You should code: CNotify* pToBeNotified = (CMyDialog*)GetParent(); to allow the compiler correctly resolve pointers to v-tables. HTH --- Kostya Sebov. ---------------------------------------------------------------------------- Tel: (38 044) 266-6387 | Fax: (38 044) 266-6195 | E-mail: sebov@is.kiev.ua
| Вернуться в корень Архива |