Short answer
No, it is not possible to achieve this witout redirecting the calls of age
, height
and worker_func
.
Longer answer
I investigated whether the use virtual derivation might help but it doesn't (see also Virtual base classes
C++ reference, Derived classes).
Tried code:
#include <iostream>
using std::cout;
// abstract Person
class I_Person
{
public:
virtual int age() = 0;
virtual int height() = 0;
};
// concrete person
class Person
{
public:
Person() = default;
virtual int age();
virtual int height();
};
class I_Worker : virtual public I_Person
{
public:
virtual ~I_Worker() = default;
virtual void worker_func() = 0;
};
class Worker : virtual public I_Worker, virtual public Person
{
// override I_Person functions here with concrete Person functions
};
int main( int /*argc*/, char *[]/*argv*/ )
{
Worker w;
I_Person* pip = &w;
I_Worker* piw = &w;
cout << "age = " << pip->age() << '\n';
cout << "height = " << pip->height() << '\n';
piw->worker_func();
return 0;
}
It just produces compiler errors:
src/lib/m1.cpp:43:21: error: variable type 'm1::Worker' is an abstract class
Worker w;
^
src/lib/m1.cpp:16:17: note: unimplemented pure virtual method 'age' in 'Worker'
virtual int age() = 0;
^
src/lib/m1.cpp:17:17: note: unimplemented pure virtual method 'height' in 'Worker'
virtual int height() = 0;
^
src/lib/m1.cpp:33:18: note: unimplemented pure virtual method 'worker_func' in 'Worker'
virtual void worker_func() = 0;
Reasonable approach
If you have a concrete Worker
and a concrete Person
than you can combine it to a WorkerPerson
without redirecting calls. Wouldn't that be the "right" approach?
Working code:
#include <iostream>
using std::cout;
// abstract Person
class I_Person {
public:
virtual int age() = 0;
virtual int height() = 0;
};
// abstract Worker
class I_Worker {
public:
virtual void worker_func() = 0;
};
// concrete Person
class Person : public I_Person {
public:
int age() {
return 33;
}
int height() {
return 167;
}
};
// concrete Worker
class Worker : public I_Worker {
virtual void worker_func() {
cout << "worker_func executed" << '\n';
};
};
class WorkerPerson : public Worker, public Person {
};
int main( int /*argc*/, char *[]/*argv*/ )
{
WorkerPerson wp;
I_Person* pip = ℘
I_Worker* piw = ℘
cout << "age = " << pip->age() << '\n';
cout << "height = " << pip->height() << '\n';
piw->worker_func();
return 0;
}
Compiles warning free, and creates output:
age = 33
height = 167
worker_func executed