Context: I was discussing C# vs. Java at work when the following question came up, and I wondered how (or if) it could be elegantly resolved in C++.
Let's say you have two classes A and B (whose details are not important) and then two templated class G and H described as something like:
template <typename T> | template <typename T>
class G | class H
{ | {
public : | public :
T * foo() ; | virtual T * foo() = 0 ;
// etc. | // etc.
} ; | } ;
Then we have the class C and D described like:
class A { /* ... */ } ;
class B { /* ... */ } ;
class C : public G<A>, public G<B>
{
} ;
class D : public H<A>, public H<B>
{
// ???
} ;
I want to be able to call for C the method foo from G<A> and foo from G<B>. And I want to be able to override for D the method foo from H<A> and H<B>.
In the end, I want to be able to use C and D like in the following examples:
C c ;
A * a = c.??? ; (I want to call G<A>::foo())
B * b = c.??? ; (I want to call G<B>::foo())
D d ;
A * a = c.??? ; (I want to call H<A>::foo())
B * b = c.??? ; (I want to call H<B>::foo())
There always are ways to do it (and I have some ideas), but I'm interested a list of elegant and safe ways to do it, including pros/cons.
So, how would you do it?
The two ways I can think of:
C x;
x.G<A>::foo(); // 1
static_cast<G<A>&>(x).foo(); // 2
That is: either explicitly qualifying the function’s name, or upcast in the type hierarchy.
How about, overloading and using different arguments :
template <typename T>
class G
{
public:
T * foo(T &a) {/* ... */};
// etc.
};
class A
{
public:
/* ... */
};
class B
{
public:
/* ... */
};
class C : public G<A>, public G<B>
{
public:
using G<A>::foo;
using G<B>::foo;
};
int main()
{
C c;
A a;
B b;
c.foo(a);
c.foo(b);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With