Re: public inheritance of interfaces and virtual (multiple) inheritanc
Alibek Jorajev wrote:
Hi !
I would like to use (1) public inheritance
of interfaces and (2) virtual (multiple) inheritance
with MFC. This is real
life case and I thought 10 times before I decided to go for it.
All other approaches based on single inheritance just
don't help.
Particularly, I have 2 abstract base interface classes,
which define pure virtual member functions. Let's call them
i_BaseA and i_BaseB (where i_ stands for interface).
Then I have
class i_BaseA
{
// specifies pure virtual functions.
// contains no data.
};
class Dlg : public CDialog, public virtual i_BaseA
{
// implements common dialog things.
};
class i_MainDlg : public virtual i_BaseA
{
// ... adds addional pure virtual functions.
// contains no data.
};
class MainDlg : public Dlg, public i_MainDlg
{
//...
};
i_BaseB is "kind of " i_BaseA, conceptually close.
There is a warning,
warning C4250: 'MainDlg' : inherits 'Dlg::Open' via dominance
which I consider as expected one and ok for me.
Only one inheritance line exists, where implementation is inherited.
I intended to keep one implementation inheritance line anyway.
But this code gives yet another warning in
BEGIN_MESSAGE_MAP(IncomingDlg, Dlg) ... END_MESSAGE_MAP()
warning C4407: cast between different pointer to member
representations,
compiler may generate incorrect code.
So I used /vmg and /vmv flags. These flags removed this warning.
Pointers to member functions became 16 byte.
However, the program crashes ! in different cases in different
places.
For example,
ON_BN_CLICKED( ..., OnSomething ) internally uses unions and
complex hacks. So this created even more doubts in me.
Then I just compiled everything without /vmg and /vmv flags and it
works !
but still, I am not sure that this is ok. This copying of bigger
pointers into smallers ones (ok, smaller planned space in a union)
worries me a lot.
Can you comment on this? is this ok, or should I take more pains and
find solutions without virtual inheritance?
First thing I'd do is get rid of the virtual inheritance - you don't need
it. Since your interfaces are pure, it doesn't matter if you have multiple
"copies" of the (empty) interface class in your object.
In GCC, all worked without any warnings, and no additional compiler
flags were used. It seems they are using 8 byte representation for
pointers to member functions and use thunks to make memory address
adjustments.
Compiling with /vmb /vmv should be equivalent to what GCC uses. Make sure
you set these options at the project level, not on individual files.
Do you ever declare a pointer-to-member to an incomplete class? If you
don't, then using /vmb will never fix a problem (but neither should it
create one).
Are you sure that the crashes are related to pointer-to-member size?
-cd