Невозможно сделать в точности то, что вы планируете (и для этого есть веская причина).
Ваш код также по своей сути сломан, поскольку вы используете тип vector<Employee>
, для которого требуются объекты типа Employee
, которые не могут существовать, поскольку Employee
является абстрактным классом. Вместо этого вы можете использовать vector
ссылочного типа, например, vector<shared_ptr<Employee>>
. (В остальной части этого ответа этот факт замалчивается, чтобы сделать его более читабельным.)
Также обратите внимание, что void Manager::set_vec_subordinate(vector<Worker> vec_employee) override { this->set_vec_subordinate(vec_employee); };
вызовет бесконечный цикл (вероятно, приводящий к переполнению стека) при вызове, так как он будет продолжать вызывать сам себя.
У класса Employee
есть контракт со своими пользователями, в котором говорится, что следующий код должен быть допустимым (при условии заданных функций get_boss
и get_workers
):
Employee& boss = get_boss();
vector<Employee> subordinate_vec = get_workers();
boss.set_vec_subordinate(subordinate_vec);
Это может не иметь семантического смысла для вашего приложения, но синтаксис языка программирования означает, что это должно быть возможно. Некоторые языки программирования (не C++!) допускают подобные ковариантные вызовы:
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
Хотя действительно возможно создать контейнер в C++, который ведет себя таким образом, что такое использование возможно, с этим проще справиться, сделав функцию set_vec_subordinate
шаблоном, который требует произвольного контейнера объектов, которые неявно преобразуемы или производное от Employee
, а затем просто преобразование объектов во время операции копирования (поскольку вектор в этом случае все равно не перемещается).
Вторая идея заключается в том, что должна быть возможность изменить сигнатуру функции при ее переопределении. Это возможно в C++ путем реализации базового варианта (который должен быть бинарно-совместимым с, т. е. равным, сигнатурой версии Employee
, поскольку она будет вызываться и в этом случае), а затем добавлением дополнительных перегрузок. Например, вы можете сделать что-то вроде:
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
};
};
person
gha.st
schedule
07.05.2020
vector<Manager>
(в отличие отEmployee
). - person Jarod42   schedule 07.05.2020