Reputation: 147
Probably best explained with an example:
struct A
{
virtual void foo() = 0;
};
struct B
{
virtual void foo() = 0;
};
struct C : A, B
{
// Implementation of A::foo
void A::foo();
// Implementation of B::foo
void B::foo();
};
// Define here; howto?
I'm aware I can define the functions inline with the class however that's not feasible in this instance (there are about 6 base classes to implement all with 40+ methods)
--
Apparently I wasn't clear enough. The question directly is: How to define both foo() methods that have been inherited without causing ambiguity issues?
The following does indeed work
void C::foo() { /* etc */ }
This will define the implementation of A::foo() yet what of B::foo() ? Bearing in mind I do not wish to define the methods within the declaration of C.
P.S., the reason for modelling the problem this way at all is predefined (COM/OLE)
--
This is fine (MSVC) albeit inline:
struct A { virtual int foo() = 0; };
struct B { virtual int foo() = 0; };
struct C : A, B
{
int A::foo() { return 1; }
int B::foo() { return 2; }
};
void main()
{
C* p = new C();
cout << ((A*) p)->foo();
cout << ((B*) p)->foo();
}
Upvotes: 0
Views: 626
Reputation: 254431
You can't provide separate overrides for two functions with the same signature defined in two base classes. (You can't define them inline within the class either, as you seem to think).
One possibility is to introduce intermediate base classes to rename the functions:
struct ABodge : A
{
void foo() {A_foo();}
virtual void A_foo() = 0;
};
struct BBodge : B
{
void foo() {B_foo();}
virtual void B_foo() = 0;
};
struct C : ABodge, BBodge
{
void A_foo();
void B_foo();
};
Alternatively, you could avoid multiple inheritance by composing two internal classes, each of which implement one of the base class interfaces:
class C
{
public:
// Could probably be defined as `operator A&()`, etc. to look more like
// inheritance, but I usually prefer conversions to be explicit.
A & asA() {return a;}
A const & asA() const {return a;}
B & asB() {return b;}
B const & asB() const {return b;}
private:
// These might need back-references to the 'C' that contains them.
struct AImpl : A {void foo();} a;
struct BImpl : B {void foo();} b;
};
Upvotes: 4
Reputation: 476990
Works as expected:
struct A { virtual void foo() = 0; };
struct B { virtual void foo() = 0; };
struct C : A, B { virtual void foo(); };
void C::foo() { }
For any C x;
, static_cast<A&>(x).foo()
and static_cast<B&>(x).foo()
will call x.foo()
as expected, which is precisely what the pure-virtual interfaces of A
and B
promise.
Upvotes: 1