Topic: Questions about multiple inheritance.


Author: Waranun Bunjongsat <bunjonwa@trek.CS.ORST.EDU>
Date: 1999/09/10
Raw View
On Thu, 9 Sep 1999, Ron Natalie wrote:

>
>
> Waranun Bunjongsat wrote:
> >
> >    APtr = static_cast<&B>(&aD);   //point to B's copy of A
> >    Aptr = static_cast<&C>(&aD);   //point to C's copy of A
>
> Eh?
>      Aptr = static_cast<C*>(&aD);

 Oh, yeah ...

Thanks,

Waranun,
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Thomas_Matthews@tecmar.com
Date: 1999/09/08
Raw View
In article <37d65508.0@newsfeed.jdedwards.com>,
  "Jerry" <jerrydung@yahoo.com> wrote:
>
> Hi,
>     I have questions about the multiple inheritance. I wsh that
someone can
> help me to figure out this:
>
> class A{.....};
> class B : public A { ....};
> class C : public A { ....};
> class D : public B, public C {.....};
> void main()
> {
>    A *pa;
>    D  d;
>
>    pa = &d;
> // -> Compiler error : '=' : ambiguous conversions from 'class D *' to
> 'class A *'
> }
>    Is it because the compiler D don't know D inherited A also,
although it
> is not specified in the D's declaration?   By the way, I am using the
VC++.
> Thanks in advance!!
>
> Jerry

The problem stems from using "void main()".  The main() function returns
int.  Always.  Anything else generates unpredictable behavior.

Other than that, class D inherits from two copies of class A, so the
compiler states that this is ambiguous (draw a picture if you need to).
 This is a classic paradigm with multiple inheritance.

The method around this is to use virtual inheritance:
class A;
class B: virtual public A;
class C: virtual public A;
class D: public B, public C;


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: postmast.root.admi.gov@iname.com (blargg)
Date: 1999/09/09
Raw View
In article <n2BB3.8207$0M6.180284@news1.rdc2.on.home.com>, "John Smith"
<jraft@home.com> wrote:

> This is one of those fuzzy areas that's difficult to quickly explain.

I think Ron Natalie's simple diagram makes it painfully clear and obvious.

> You should be able to correct your problem by simply making the two
> following changes:
>
> class B : public virtual A { ....};
> class C : public virtual A { ....};

No. The problem isn't with the implementation; it's with the design. The
design is not thought out properly. If it calls for B and C to both have
their own A sub-objects, and for some client using class D, which derived
from B and C, to be able to unambiguously convert to A, then it's broke.
You can't fix it by violating the design and having only one A sub-object
for a D object.

Virtual derivation isn't a fix to a problem; it's simply a tool to be used
in a design. Don't apply it mindlessly as a "fix" when you are faced with
ambiguity.

[snip]


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Waranun Bunjongsat <bunjonwa@trek.CS.ORST.EDU>
Date: 1999/09/09
Raw View
On 9 Sep 1999, blargg wrote:

>
> In article <n2BB3.8207$0M6.180284@news1.rdc2.on.home.com>, "John Smith"
> <jraft@home.com> wrote:
>
> > This is one of those fuzzy areas that's difficult to quickly explain.
>
> I think Ron Natalie's simple diagram makes it painfully clear and obvious.
>
> > You should be able to correct your problem by simply making the two
> > following changes:
> >
> > class B : public virtual A { ....};
> > class C : public virtual A { ....};
>
> No. The problem isn't with the implementation; it's with the design. The
> design is not thought out properly. If it calls for B and C to both have
> their own A sub-objects, and for some client using class D, which derived
> from B and C, to be able to unambiguously convert to A, then it's broke.
> You can't fix it by violating the design and having only one A sub-object
> for a D object.
>
> Virtual derivation isn't a fix to a problem; it's simply a tool to be used
> in a design. Don't apply it mindlessly as a "fix" when you are faced with
> ambiguity.

 Yes, you're right. The issue here is that the class designer wants
B and C to have their own copy of A, or not.

 If not, he should use virtual inheritance.

 If yes, he can do this.

class A { ... }
class B : public A {...}
class C : public A {...}
class D : public B, C {...}

int main()
{
   A* APtr;
   D  aD;
   APtr = static_cast<&B>(&aD);   //point to B's copy of A
   Aptr = static_cast<&C>(&aD);   //point to C's copy of A
}


Regards,

Waranun,



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Ron Natalie <ron@sensor.com>
Date: 1999/09/09
Raw View


Waranun Bunjongsat wrote:
>
>    APtr = static_cast<&B>(&aD);   //point to B's copy of A
>    Aptr = static_cast<&C>(&aD);   //point to C's copy of A

Eh?
     Aptr = static_cast<C*>(&aD);



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/09
Raw View
In article <37d65508.0@newsfeed.jdedwards.com>, Jerry
<jerrydung@yahoo.com> writes
>
>Hi,
>    I have questions about the multiple inheritance. I wsh that someone can
>help me to figure out this:
>
>class A{.....};
>class B : public A { ....};
>class C : public A { ....};
>class D : public B, public C {.....};
>void main()

Please note that despite what VC++ may say this line should be
int main()
>{
>   A *pa;
>   D  d;
>
>   pa = &d;
>// -> Compiler error : '=' : ambiguous conversions from 'class D *' to
>'class A *'

and to keep VC++ happy you will need:
return 0;
here
>}
>   Is it because the compiler D don't know D inherited A also, although it
>is not specified in the D's declaration?   By the way, I am using the VC++.
>Thanks in advance!!

No.  Because of the B and C both derived from A, D will contain two A
subobjects and the compiler rightly complains that it does not know
which one you want to use.

Now whether D should contain two or one A subobject will entirely depend
on what you are doing.  But to discover how to make the B and the C
share the same A you need to read up about virtual base classes.

>
>Jerry
>
>jerrydung@yahoo.com
>
>
>
>
>
>
>
>[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
>[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
>[              --- Please see the FAQ before posting. ---               ]
>[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]
>

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "John Smith" <jraft@home.com>
Date: 1999/09/09
Raw View
On the contrary, this is a fuzzy area involving an abstract undertanding of
shared base classes. There's more to it than drawing a simple DAG (Direct
Acyclic Graph). You need to understand potentially complex relationships and
this is not a trivial task. As for my advice, it was a mechanical
demonstration with instructions to learn about virtual base classes. It
wasn't a dissertation on the subject. Stop treating it as such.

blargg <postmast.root.admi.gov@iname.com> wrote in message
news:user-0809991923030001@aus-as3-109.io.com...
>
> In article <n2BB3.8207$0M6.180284@news1.rdc2.on.home.com>, "John Smith"
> <jraft@home.com> wrote:
>
> > This is one of those fuzzy areas that's difficult to quickly explain.
>
> I think Ron Natalie's simple diagram makes it painfully clear and obvious.
>
> > You should be able to correct your problem by simply making the two
> > following changes:
> >
> > class B : public virtual A { ....};
> > class C : public virtual A { ....};
>
> No. The problem isn't with the implementation; it's with the design. The
> design is not thought out properly. If it calls for B and C to both have
> their own A sub-objects, and for some client using class D, which derived
> from B and C, to be able to unambiguously convert to A, then it's broke.
> You can't fix it by violating the design and having only one A sub-object
> for a D object.
>
> Virtual derivation isn't a fix to a problem; it's simply a tool to be used
> in a design. Don't apply it mindlessly as a "fix" when you are faced with
> ambiguity.
>
> [snip]
>
>
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]
>
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Jerry" <jerrydung@yahoo.com>
Date: 1999/09/08
Raw View
Hi,
    I have questions about the multiple inheritance. I wsh that someone can
help me to figure out this:

class A{.....};
class B : public A { ....};
class C : public A { ....};
class D : public B, public C {.....};
void main()
{
   A *pa;
   D  d;

   pa = &d;
// -> Compiler error : '=' : ambiguous conversions from 'class D *' to
'class A *'
}
   Is it because the compiler D don't know D inherited A also, although it
is not specified in the D's declaration?   By the way, I am using the VC++.
Thanks in advance!!

Jerry

jerrydung@yahoo.com







[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "John Smith" <jraft@home.com>
Date: 1999/09/08
Raw View
This is one of those fuzzy areas that's difficult to quickly explain. You
should be able to correct your problem by simply making the two following
changes:

class B : public virtual A { ....};
class C : public virtual A { ....};

Check out the documentation on virtual base classes. You show know about
this anyway when dealing with multiple inheritance.

Jerry <jerrydung@yahoo.com> wrote in message
news:37d65508.0@newsfeed.jdedwards.com...
>
> Hi,
>     I have questions about the multiple inheritance. I wsh that someone
can
> help me to figure out this:
>
> class A{.....};
> class B : public A { ....};
> class C : public A { ....};
> class D : public B, public C {.....};
> void main()
> {
>    A *pa;
>    D  d;
>
>    pa = &d;
> // -> Compiler error : '=' : ambiguous conversions from 'class D *' to
> 'class A *'
> }
>    Is it because the compiler D don't know D inherited A also, although it
> is not specified in the D's declaration?   By the way, I am using the
VC++.
> Thanks in advance!!
>
> Jerry
>
> jerrydung@yahoo.com
>

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Ron Natalie <ron@sensor.com>
Date: 1999/09/08
Raw View


Jerry wrote:
>
> void main()

Main must return int.  Get used to it.

>    Is it because the compiler D don't know D inherited A also, although it
> is not specified in the D's declaration?   By the way, I am using the VC++.
> Thanks in advance!!

No, it's because it doesn't know which A you want.  You have two A's in
the inheritance tree.   Looks like this:

 A   A
 |   |
 B   C
        \  /
          D

The compiler doesn't know how to convert from D* to A*, because it doesn't
know whether to use the A inherited through B or the one inherited through
C.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Albela Kela" <albelakela@hotmail.com>
Date: 1999/09/08
Raw View
class D has inherited two kinds of A - One through B and another through C.
How does the poor compiler know which one are you referring to?

Lets take an example. Class A suppose is a NamedObject class :

class NamedObject
{

   public:    // should not do this but doesnt matter here.
        string name;
        NamedObject( const string & rhs) : name(rhs) {}
}

Any class whose objects have a name can inherit from NamedObject:

class B : public NamedObject
{
  public:
    B(const string & rhs) : NamedObject(rhs){}
...... // B specific funcs
}

class C : public NamedObject
{
  public:
    C(const string & rhs) : NamedObject(rhs){}
...... // C specific funcs
}

Now suppose D derives (publically) from B and C.
class C : public B, public C{
  public:
    D(const string & rhs1, const string & rhs2) : B(rhs1), C(rhs2){}
...... // D specific funcs
}


Now consider a main function

int main()
{
    D d("B_Name", "C_Name");
    A* pa;

    pa = &d;

    cout << pa->name;
}

So now what name should D have?

If you could constrain D to have a single A by something called virtual
inheritance this problem wont arise.


Anyway if you RTFM or MSDN its explained clearly in there.


Jerry <jerrydung@yahoo.com> wrote in message
news:37d65508.0@newsfeed.jdedwards.com...
>
> Hi,
>     I have questions about the multiple inheritance. I wsh that someone
can
> help me to figure out this:
>
> class A{.....};
> class B : public A { ....};
> class C : public A { ....};
> class D : public B, public C {.....};
> void main()
> {
>    A *pa;
>    D  d;
>
>    pa = &d;
> // -> Compiler error : '=' : ambiguous conversions from 'class D *' to
> 'class A *'
> }
>    Is it because the compiler D don't know D inherited A also, although it
> is not specified in the D's declaration?   By the way, I am using the
VC++.
> Thanks in advance!!
>
> Jerry
>
> jerrydung@yahoo.com

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]