Assume the following:
class A{ virtual void f() = 0; };
class B{ virtual void f() = 0; };
Can I do the following somehow?
class C : public A, public B
{
virtual void A::f(){ printf("f() from A"); }
virtual void B::f(){ printf("f() from B"); }
};
So now I can do???
A* pa = new C();
pa->f(); // prints f() from A;
B* pb = (B*)pa;
pb->f(); // prints f() from B;
Thanks!!!
But C# does not support multiple class inheritance. To overcome this problem we use interfaces to achieve multiple class inheritance. With the help of the interface, class C( as shown in the above diagram) can get the features of class A and B.
You can derive a class from any number of base classes. Deriving a class from more than one direct base class is called multiple inheritance. The order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors.
A class can be derived from more than one base class. In a multiple-inheritance model (where classes are derived from more than one base class), the base classes are specified using the base-list grammar element.
First solution
This question remind the 'facade' design pattern. This should be re-write as this :
class AC : public A
{ public: virtual void f(){ cout << "f() from A" << endl;}; };
class BC : public B ...
class C : public AC, public BC {};
where C is the 'facade'.
So in the correct calling syntax should be something like that :
C* c = new C();
c->AC::f();
c->BC::f();
If you don't have any share constraint between AC & BC this should do the job as it is'nt offuscated.
Second solution
Another solution, thank to Casey (see first comment), is to use a forward declaration of the class C in a template to allow calls to methods define latter.
template <typename C>
class AC : public A {
public:
void f() { static_cast<C&>(*this).f_from_A(); }
};
template <typename C>
class BC : public B { ... };
so the implementation part can be done in the same class.
class C : public AC<C>, public BC<C> {
public:
void f_from_A() { cout << "f_from_A" << endl; };
void f_from_B() ...
};
The calling part is cleaner because it doesn't show any implementation details and it is closest to the question :
C* c = new C();
((A*) c) -> f();
((B*) c) -> f();
There is no more 'default' f() on C and it is possible to break the expected behavior of inheritance, and it is harder to read.
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