如何在派生类上强制派生类成员

时间:2019-07-02 17:15:37

标签: c++ oop inheritance design-patterns

如何强制派生类具有特定派生类型的成员数据。

class Project {
  public:
    int projdata;
};

class Article: public Project {
};

class Building: public Project {
};

class Emplooyee {
  public:
    std::vector<Project> projs;
}

class Architect: public Employee {
};

class Writer: public Employee {
};

我现在如何强制Architect对象仅具有Building类型的项目,而Novelist仅具有Article类型的项目?即,我想要类似的东西

class Architect: public Employee {
  public:
    std::vector<Building> projs;
};

class Novelist: public Employee {
  public:
    std::vector<Article> projs;
};

我还可以存储指向项目的指针,然后将其转换为正确的类型。是否有一种技术或设计模式可以在派生类的成员上强制执行此类相应的继承规则?

2 个答案:

答案 0 :(得分:2)

一种编译时的解决方案是使基础成为模板:

template<class Proj>
class Emplooyee {
  public:
    std::vector<Proj> projs;
}

class Architect: public Employee<Building> {};

class Writer: public Employee<Article> {};

此外,您可以添加一个其他的非模板库,以使ArchitectWriter属于同一层次结构,但是该非模板库不能处理projs成员

如果不是模板,则必须依靠运行时检查。为此,Project必须是多态类型,并且必须使用typeiddynamic_cast来强制不变量。并且您必须首先使用间接存储Projectstd::vector<Project>无法存储任何BuildingArticle对象,因为它仅存储Project个对象

答案 1 :(得分:0)

就像您提到的那样,您可以在基类中存储多态指针:

class Employee {
  public:
    std::vector<Project*> projs;
}

并使用dynamic_cast对其进行下调:

dynamic_cast<Building*>(projs[i])->doSomething();

但是我不推荐这种方法(除非必要),因为这将需要您管理这些指针后面的内存。 (例如,当然可以将其卸载到std::unique_ptr。)

除非您要求Employee是多态类,否则更简单的方法是使用类模板

template <typename T>
class Employee {
public:
    std::vector<T> projs;
}

可以这样使用:

class Architect : public Employee<Building> {
};

Architect architect;
architect.projs.push_back(Building());