用派生类型的不同参数覆盖纯虚函数

Override pure virtual function with different parameter of derived type

关于这个主题有很多问题,但是,我没有找到以下问题的解决方案:

我有以下 classes:

1)纯虚class

class Employee {
private:
    vector<Employee> vec_employee;

public:
    Employee() {};
    virtual ~Employee() {};
    virtual void set_vec_subordinate(vector<Employee> vec_employee) = 0;
};

2) 派生class

class Worker : Employee{ private: public: };

3) 另一个派生 class 应该覆盖 Employee

的纯虚方法
class Manager : Employee {
private:
public:
    inline void set_vec_subordinate(vector<Worker> vec_employee) override { this->set_vec_subordinate(vec_employee); };
};

我试图实现的是覆盖纯虚方法但使用 "different" 参数。所以对 C++ 来说仍然是新手,但我认为应该有一种方法可以做到这一点,特别是因为 另一个参数来自 Worker 类型,它是从 Employee 派生的 class。

没有办法完全您计划做的事情(这是有充分理由的)。

你的代码本身也有问题,因为你使用类型 vector<Employee>,它需要类型 Employee 的对象——它不存在,因为 Employee 是一个抽象 class.您可能希望使用引用类型的 vector,例如 vector<shared_ptr<Employee>>。 (此答案的其余部分掩盖了这一事实以使其更具可读性。)

另请注意,void Manager::set_vec_subordinate(vector<Worker> vec_employee) override { this->set_vec_subordinate(vec_employee); }; 在调用时会导致无限循环(可能导致堆栈溢出),因为它会一直调用自己。

class Employee 与其用户签订了合同,规定以下代码必须有效(假设给定 get_bossget_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++ 中是可能的,通过实现基本情况(需要二进制兼容 - a.k.a。等于 - 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
    };
};