用派生类型的不同参数覆盖纯虚函数
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_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++ 中是可能的,通过实现基本情况(需要二进制兼容 - 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
};
};
关于这个主题有很多问题,但是,我没有找到以下问题的解决方案:
我有以下 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_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++ 中是可能的,通过实现基本情况(需要二进制兼容 - 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
};
};