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.