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! ]
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
> 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.
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?
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);
};
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
> 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
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
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
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.