代码C ++中的动态多态性错误

时间:2016-09-04 13:38:59

标签: c++ dynamic polymorphism

#include<iostream>

struct I {
    virtual void et() = 0;
};

struct Data {
    int foo;
    double bar;
};

template<typename... T>
struct S: I, Data, private T... {
    S(): Data{}, T{}... {}

    void et() override {
        int arr[] = { (T::et(*this), 0)..., 0 };
        (void)arr;
        std::cout << "S" << std::endl;
    }
};

struct A {
    void et(Data &) {
        std::cout << "A" << std::endl;
    }
};

struct B {
    void et(A &) {
        std::cout << "B" << std::endl;
    }
};

int main() {
    I *ptr = new S<A,B>{};
    ptr->et();
    delete ptr;
}

/ 如果编译此代码,有错误的行显示错误。 我想知道是否可以通过staff指针访问getEngineer(),getManager(),getDirector()。 如果是,那怎么样? 如果没有,那么为什么呢? 是否有任何替代方法可以访问那些保持员工数据类型的函数(即员工)? /

2 个答案:

答案 0 :(得分:3)

来自Employee的所有派生类必须实现所有纯虚方法,否则无法实例化。

为什么会这样?

衍生类从基类继承所有方法(和成员变量)。

在这种情况下,基类有一些纯虚方法,所以子类(EngineerManagerDirector)也是如此。无抽象类不能有纯虚方法,因此为了实例化这些类,每个类都应该实现getEngineer() getManager() getDirector()方法。 / p>

解决方案是什么?

您的案例中的问题是糟糕的设计决策。 基类应代表所有派生类的统一接口

这就是为什么,基类Employee不应该有像getEngineer()这样的方法,这是一个更具体的信息。

IMO,一个更好的设计决策(只看你的代码)可能是:

class Employee {
 public :
  virtual int calculateSalary() = 0;
  virtual string getName() = 0;      
  virtual string getTypeWork() = 0;
};

以这种方式(利用多态属性),每个派生类都可以正确返回表示其角色作业的字符串。

答案 1 :(得分:1)

  

可以通过staff指针访问getEngineer(),getManager(),getDirector()。如果是,那怎么办?

是的,你可以。但是,正如@Biagio Festa所说,你不能在你的基类Employee中拥有纯虚函数而不在你的派生类中实现它们。因此,一种解决方案可能是为基类中的那些函数提供默认实现

class Employee
{
 public :
  virtual int calculateSalary()= 0;
  virtual string getName()=0;      
  virtual string getEngineer() { return std::string(); }            
  virtual string getManager() { return std::string(); }
  virtual string getDirector() { return std::string(); }            
};

然后,您可以仅在需要时在您的派生类中覆盖这些函数,就像您在示例中所做的那样。