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 Kurtinitis
Hi 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 Kurtinitis
Hi 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
| Вернуться в корень Архива
|