Re: public inheritance of interfaces and virtual (multiple) inheri
- From: Alibek Jorajev <AlibekJorajev@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Mon, 9 Jul 2007 07:30:01 -0700
Hi Carl !
thanks for fast reply.
Of course, I will not cling to the death to use virtual inheritance.
But having virtual inheritance gives a nice possibility to use
i_MainDlg also to call functions specified in i_BaseA. Then,
such function call gets nicely delegated to Dlg (I think this is
almost same as using delegation to a sister class via virtual inheritance,
but here we restrict ourselves having only interfaces in second line and one
line
of implementation inheritance). By this way, the user of MainDlg does not
need to swap pointers to i_Base_A and i_MainDlg, but can use all services
provided by MainDlg via single pointer (which can be obtained from
Singleton/factory) for example.
And yes, I made sure that /vmg /vmv are set every place, not
just for one individual file (I used Visual C++ 2005 in Studio 2005 ver.
8.0.50727.42). At each project of my solution.
However, I thought that /vmg is more general case and thus safer.
I will try now to use /vmb.
However, in MFC, you need to declare a pointer to a member of a class
before defining the class. in message mapping. and then, in the same cpp
file,
class is defined. Alghough there is not mutually referencing classes, can it
be still a problem?
class. This need can arise if you define members in two different classes
that reference each other. For such mutually referencing classes, one class
must be referenced before it is defined.
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).
- No, I never declared such pointer, but codebase is large. so I need
to check it.
Are you sure that the crashes are related to pointer-to-member size?
-- No, of course, I am not sure. But what I sure is that system crashes
because of /vmg /vmv. and crashes at random places. exactly same code with
and without these compiler switches. This was all what I did.
Without them it works fine. But warnings - they suggest that without these
compiler switches, we can end up corrupting pointers.
I will try with /vmg /vmv now.
but still, it not clear for me -- why it works without them ?
and the main question is that - is it safe to use bigger pointer to member
representations with MFC?
regards,
Alibek.
"Carl Daniel [VC++ MVP]" wrote:
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
- Follow-Ups:
- Re: public inheritance of interfaces and virtual (multiple) inheri
- From: Carl Daniel [VC++ MVP]
- Re: public inheritance of interfaces and virtual (multiple) inheri
- References:
- public inheritance of interfaces and virtual (multiple) inheritanc
- From: Alibek Jorajev
- Re: public inheritance of interfaces and virtual (multiple) inheritanc
- From: Carl Daniel [VC++ MVP]
- public inheritance of interfaces and virtual (multiple) inheritanc
- Prev by Date: Re: public inheritance of interfaces and virtual (multiple) inheritanc
- Next by Date: Re: public inheritance of interfaces and virtual (multiple) inheri
- Previous by thread: Re: public inheritance of interfaces and virtual (multiple) inheritanc
- Next by thread: Re: public inheritance of interfaces and virtual (multiple) inheri
- Index(es):
Relevant Pages
|