Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multiply inherit from classes with conflicting function names

2 views
Skip to first unread message

Adam

unread,
May 23, 2006, 5:53:18 PM5/23/06
to
I have an unfortunate case where a single class wants to derive from two
existing classes:

struct A { virtual long fun() = 0; };
struct B { virtual bool fun() = 0; };
struct Unfortunate : public A, public B { ??? };

Is it possible to fill in the ??? here with legal code?
I need two different function bodies; A::fun and B::fun do unrelated
things.

More or less the same question with a twist: if A::fun and B::fun both
returned the same type, would it be possible to implement two functions
in C such that
C().A::fun()
and
C().B::fun()
would execute two different functions?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

aceh...@yahoo.com

unread,
May 24, 2006, 11:36:11 AM5/24/06
to
Adam wrote:
> I have an unfortunate case where a single class wants to derive from two
> existing classes:
>
> struct A { virtual long fun() = 0; };
> struct B { virtual bool fun() = 0; };
> struct Unfortunate : public A, public B { ??? };
>
> Is it possible to fill in the ??? here with legal code?

You can introduce trivial intermediate classes to "rename" the
functions.

> I need two different function bodies; A::fun and B::fun do unrelated
> things.
>
> More or less the same question with a twist: if A::fun and B::fun both
> returned the same type, would it be possible to implement two functions
> in C such that
> C().A::fun()
> and
> C().B::fun()
> would execute two different functions?

The intermediate classes would still work, but with a different syntax:

C().A_fun();

Here is a complete test:

#include <iostream>

struct A { virtual long fun() = 0; };
struct B { virtual bool fun() = 0; };

struct A_impl : public A
{
virtual long A_fun() = 0;
virtual long fun()
{
return A_fun();
}
};

struct B_impl : public B
{
virtual bool B_fun() = 0;
virtual bool fun()
{
return B_fun();
}
};

struct Unfortunate : public A_impl, public B_impl
{
virtual long A_fun()
{
std::cout << "long\n";
return 0;
}

virtual bool B_fun()
{
std::cout << "bool\n";
return false;
}
};

int main()
{
Unfortunate u;

// Ambiguous to call fun()
u.A_fun();
u.B_fun();

// No ambiguity through the base interfaces
A & a = u;
a.fun();
B & b = u;
b.fun();
}

Ali

Carl Barron

unread,
May 24, 2006, 11:33:46 AM5/24/06
to
In article <15-dnUdwgJl...@speakeasy.net>, Adam
<usenet...@aulick.net> wrote:

> I have an unfortunate case where a single class wants to derive from two
> existing classes:
>
> struct A { virtual long fun() = 0; };
> struct B { virtual bool fun() = 0; };
> struct Unfortunate : public A, public B { ??? };
>

give them new names by adding mid_A,mid_B to the inheritance?

struct mid_A:A {virtual long fun();long fun_A(){return fun();}};
struct mid_B:B {virtual bool fun(); bool fun_B(){return fun();}};
struct Unfortunate:mid_A,Mid_B {}

if these are really structs the above fun()'s can access
Unfortunates' data via a static_cast<Unfortunate *>(this);
if Unfortunate is a class then also make mid_A,mid_B friends of
Unfortunate.

Alf P. Steinbach

unread,
May 24, 2006, 11:34:18 AM5/24/06
to
* Adam, in clc++m:

> I have an unfortunate case where a single class wants to derive from two
> existing classes:
>
> struct A { virtual long fun() = 0; };
> struct B { virtual bool fun() = 0; };
> struct Unfortunate : public A, public B { ??? };

I already answered this one (the exact same message text), apparently to
Adam's satisfaction, in [clc++].

Could people please /stop/ multi-posting (at least not without noting in
the message that it's multi-posted)?

IMO it's now become a nuisance.


Note: this message has been /cross-posted/ to clc++ and clc++m.

For the difference between cross-posting and multi-posting, see Google.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Maxim Yegorushkin

unread,
May 25, 2006, 9:33:22 AM5/25/06
to
Adam wrote:
> I have an unfortunate case where a single class wants to derive
> from two
> existing classes:
>
> struct A { virtual long fun() = 0; };
> struct B { virtual bool fun() = 0; };
> struct Unfortunate : public A, public B { ??? };
>
> Is it possible to fill in the ??? here with legal code?
> I need two different function bodies; A::fun and B::fun do unrelated
> things.

Yes, you need an intermediate class here.

struct A_tag {} const a_tag = {};
struct B_tag {} const b_tag = {};

// zero overhead shim
template<class derived>
struct A_shim : A
{
long fun() { return static_cast<derived*>(this)->fun(a_tag); }
};

// virtual call overhead shim
struct B_shim : B
{
bool fun() { this->fun(b_tag); }
virtual bool fun(B_tag) = 0;
};

struct fortunate : A_shim<fortunate>, B_shim
{
long fun(A_tag);
bool fun(B_tag);
};

Nicola Musatti

unread,
May 25, 2006, 9:53:53 AM5/25/06
to

Adam wrote:
> I have an unfortunate case where a single class wants to derive
> from two
> existing classes:
>
> struct A { virtual long fun() = 0; };
> struct B { virtual bool fun() = 0; };
> struct Unfortunate : public A, public B { ??? };
>
> Is it possible to fill in the ??? here with legal code?
> I need two different function bodies; A::fun and B::fun do unrelated
> things.

The usual technique is the following:

struct AdaptA : A {
virtual long funA() = 0;
long fun() { return funA(); }
};

struct AdaptB : B {
virtual long funB() = 0;
long fun() { return funB(); }
};

struct Unfortunate : AdaptA, AdaptB {
long funA() { return 42L }
bool funB() { return false; }
};

> More or less the same question with a twist: if A::fun and B::fun
> both
> returned the same type, would it be possible to implement two
> functions
> in C such that
> C().A::fun()
> and
> C().B::fun()
> would execute two different functions?

I don't think the return type makes any difference.

Cheers,
Nicola Musatti

kanze

unread,
May 25, 2006, 9:56:21 AM5/25/06
to
Adam wrote:
> I have an unfortunate case where a single class wants to
> derive from two existing classes:

> struct A { virtual long fun() = 0; };
> struct B { virtual bool fun() = 0; };
> struct Unfortunate : public A, public B { ??? };

> Is it possible to fill in the ??? here with legal code?

Legal code, certainly. But nothing that would stop the class
from being abstract -- there's no way you can override fun().

> I need two different function bodies; A::fun and B::fun do
> unrelated things.

The classical solution is to create intermediate classes:

struct Abis { virtual long funA() = 0 ;
virtual long fun() { return funA() ; } } ;
struct Bbis { virtual bool funB() = 0 ;
virtual bool fun() { return funB() ; } } ;
struct Unfortunate : A, B
{
virtual long funA() { ... }
virtual long funB() { ... }
} ;

> More or less the same question with a twist: if A::fun and
> B::fun both returned the same type, would it be possible to
> implement two functions in C such that
> C().A::fun()
> and
> C().B::fun()
> would execute two different functions?

Same solution as above.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Adam Aulick

unread,
May 25, 2006, 11:58:49 PM5/25/06
to
Alf P. Steinbach wrote:
> Could people please /stop/ multi-posting (at least not without
> noting in
> the message that it's multi-posted)?
>
> IMO it's now become a nuisance.

For the record, posting to the moderated group was an accident in this
case. Embarassing since I've been impatient with multi-posters
elsewhere in the past, but there's karma for you. My apologies.

~Adam

Hyman Rosen

unread,
May 26, 2006, 7:49:51 AM5/26/06
to
Adam wrote:
> struct A { virtual long fun() = 0; };
> struct B { virtual bool fun() = 0; };
> struct Unfortunate : public A, public B { ??? };

The standard-conforming way to do this has already
been posted several times. Some compilers also have
a syntax extension which does the job:

struct Unfortunate : A, B {
long A::fun() { ... }
bool B::fun() { ... }
};

gottlo...@gmail.com

unread,
May 27, 2006, 6:35:35 AM5/27/06
to

Hyman Rosen wrote:
> The standard-conforming way to do this has already
> been posted several times. Some compilers also have
> a syntax extension which does the job:
>
> struct Unfortunate : A, B {
> long A::fun() { ... }
> bool B::fun() { ... }
> };
>

I'd really love it if this made it into the language! Also note that
it covers another common complaint/request: if A does NOT have a
matching virtual long fun(), then you get a compiler error - thus
making it more clear and less error-prone as to what you are
overriding.

Tony

Maxim Yegorushkin

unread,
May 28, 2006, 9:43:56 AM5/28/06
to
gottlo...@gmail.com wrote:
> Hyman Rosen wrote:
> > The standard-conforming way to do this has already
> > been posted several times. Some compilers also have
> > a syntax extension which does the job:
> >
> > struct Unfortunate : A, B {
> > long A::fun() { ... }
> > bool B::fun() { ... }
> > };
> >
>
> I'd really love it if this made it into the language! Also note that
> it covers another common complaint/request:

I don't think this is a good idea. First, the feature is rarely useful
(in fact, never in my experience). Second, it's so easy to do
needlessly complex designs in C++. It is more easier to do so when you
have more useless features.

0 new messages