C++ 如何在派生类上强制执行派生类成员
如何强制派生类具有特定派生类型的成员数据 i、 eC++ 如何在派生类上强制执行派生类成员,c++,oop,inheritance,design-patterns,C++,Oop,Inheritance,Design Patterns,如何强制派生类具有特定派生类型的成员数据 i、 e 类项目{ 公众: int-projdata; }; 班级文章:公共项目{ }; 班级建设:公共工程{ }; 雇员阶级{ 公众: std::vector projs; } 类架构师:公共雇员{ }; 课程作者:公共雇员{ }; 我现在如何强制Architect对象只有Building类型的项目,而小说家只有Article类型的项目?i、 例如,我想要一些像 class Architect: public Employee { public:
类项目{
公众:
int-projdata;
};
班级文章:公共项目{
};
班级建设:公共工程{
};
雇员阶级{
公众:
std::vector projs;
}
类架构师:公共雇员{
};
课程作者:公共雇员{
};
我现在如何强制Architect对象只有Building类型的项目,而小说家只有Article类型的项目?i、 例如,我想要一些像
class Architect: public Employee {
public:
std::vector<Building> projs;
};
类架构师:公共雇员{
公众:
std::vector projs;
};
及
职业小说家:公职人员{
公众:
std::vector projs;
};
我还可以存储指向项目的指针,然后将它们转换为正确的类型。是否有一种技术或设计模式可以在派生类的成员上强制执行此类相应的继承规则?编译时解决方案是将基类作为模板:
template<class Proj>
class Emplooyee {
public:
std::vector<Proj> projs;
}
class Architect: public Employee<Building> {};
class Writer: public Employee<Article> {};
模板
雇员阶级{
公众:
std::vector projs;
}
类架构师:公共雇员{};
类作者:公共雇员{};
此外,您可以添加一个额外的非模板库,以便Architect
和Writer
属于同一层次结构,但该非模板库不能处理projs
成员
如果模板不是选项,则必须依赖运行时检查。为此,
Project
必须是多态类型,并且必须使用typeid
或dynamic\u cast
,以强制执行不变量。您必须首先使用间接寻址来存储项目
std::vector
无法存储任何建筑
或文章
对象,因为它仅存储项目
对象如您所述,您可以在基类中存储多态指针:
class Employee {
public:
std::vector<Project*> projs;
}
但我不推荐这种方法(除非必要),因为这需要您管理这些指针后面的内存。(例如,它当然可以卸载到std::unique_ptr
)
除非您要求Employee是多态类,否则更简单的方法是使用类模板
template <typename T>
class Employee {
public:
std::vector<T> projs;
}
模板
班级员工{
公众:
std::vector projs;
}
可以这样使用:
class Architect : public Employee<Building> {
};
Architect architect;
architect.projs.push_back(Building());
类架构师:公共雇员{
};
建筑师;
architect.projs.push_back(Building());
您只需将项目子类型作为类型参数,将Employee作为模板即可。或者保留员工并使用中间EmployeeImpl模板来自动进行铸造。这在OOP中是一个巨大的反模式。为什么您关心类存储什么数据?具体来说,您想做什么,为什么不能将其作为成员函数而不是成员变量?模板参数也可以在编译时受到约束,例如,需要从项目
(ref:)项目
必须至少有一个虚拟方法才能启用动态转换
dynamic_cast<Building*>(projs[i])->doSomething();
template <typename T>
class Employee {
public:
std::vector<T> projs;
}
class Architect : public Employee<Building> {
};
Architect architect;
architect.projs.push_back(Building());