There are a lot of questions about this topic, but however, I didn't find the solution for my following question:
I have the following classes:
1) The pure virtual class
class Employee {
private:
vector<Employee> vec_employee;
public:
Employee() {};
virtual ~Employee() {};
virtual void set_vec_subordinate(vector<Employee> vec_employee) = 0;
};
2) A derived class
class Worker : Employee{ private: public: };
3) Another derived class which should override the pure virtual method from Employee
class Manager : Employee {
private:
public:
inline void set_vec_subordinate(vector<Worker> vec_employee) override { this->set_vec_subordinate(vec_employee); };
};
What I try to achieve is to override the pure virtual method but use a "different" parameter. So still new to C++ but I think there should be a way to do so, especially because the other parameter is from type Worker which is a derived class from Employee.
There is no way to do exactly what you plan to do (and there is good reason for that).
Your code is also inherently broken, as you use the type vector<Employee>
, which requires objects of type Employee
- which cannot exist, as Employee
is an abstract class. You may wish to use a vector
of a reference type, e.g., vector<shared_ptr<Employee>>
instead. (The rest of this answer glosses over this fact to make it more readable.)
Note also that void Manager::set_vec_subordinate(vector<Worker> vec_employee) override { this->set_vec_subordinate(vec_employee); };
would cause an infinite loop (probably resulting in a stack overflow) when called, as it will just keep calling itself.
The class Employee
has a contract with its users, that says the following code must be valid (assuming given get_boss
and get_workers
functions):
Employee& boss = get_boss();
vector<Employee> subordinate_vec = get_workers();
boss.set_vec_subordinate(subordinate_vec);
Now, this might not make any semantic sense for your application, but the syntax of the programming language means that this must be possible. Some programming languages (not C++!) allow covariant calls similar to this:
Employee& boss = get_boss();
vector<Worker> subordinate_vec = get_workers();
boss.set_vec_subordinate(subordinate_vec); // Invalid C++: `vector<Worker` cannot be converted to `vector<Employee>` implicitly
While it is indeed possible to create a container in C++ that behaves in a way so that this use is possible, it is easier to deal with it is by making the set_vec_subordinate
function a template that requires an arbitrary container of objects that are implicitly convertible or derived from Employee
- and then just converting the objects during the copy operation (since the vector is not movable in that case anyway).
The second idea is that it should be possible to change the signature of a function when overriding it. This is kind of possible in C++ by implementing the base case (which needs to be binary compatible with - a.k.a. equal to - the signature of the Employee
version, as it will be called for that case as well) and then adding additional overloads. For example, you could do something along the lines of:
class Manager : Employee {
private:
public:
inline void set_vec_subordinate(vector<Employee> vec_employee) override { this->vec_employee = std::move(vec_employee); };
inline void set_vec_subordinate(vector<Worker> const& vec_worker) {
vec_employee = std::vector<Employee>(vec_worker.begin(), vec_worker.end()); // copy convert all elements
};
};