我有 Components 的不同集合,其中每个Component都是抽象类 IComponent 的子类。 IComponent 定义了一个纯虚函数{{1}因此,每个组件都需要为它创建一个实现。
考虑每个组件只能添加一次,因此其ID等于所有实例和集合函数
virtual ID_TYPE getId() = 0;
我希望有一个额外的静态方法,就像上面描述的那样,以便检索组件的ID而无需按顺序创建实例(可能没有默认构造函数)像
这样的东西IComponent* ICollection::getComponent(const ID_TYPE);
我知道虚拟静态成员之类的东西并不存在,并且无法覆盖静态方法。但是可以有任何其他方法来确保collection1.getComponent(MyComponentA::getId())->something();
collection2.getComponent(MyComponentA::getId())->something();
的每个子类定义这样的静态方法吗?
答案 0 :(得分:1)
所以我会选择这样的东西:
ComponentBase.h:
template <typename T>
class ComponentBase {
....
....
protected:
ComponentBase() { (void)getClassId(); }
public:
static int getClassId();
....
};
Component1.h:
#include "ComponentBase.h"
class Component1: public ComponentBase<Component1> {
public:
Component1(....) {}
....
};
Component1.cc:
#include "Component1.h"
....
template <>
int ComponentBase<Component1>::getClassId() {
return 1;
}
如果开发人员忘记为类ComponentBase<ComponentX>::getClass()
定义ComponentX
,则该项目将不会链接。
实际上我不会将ID的选择留给组件开发人员。这种技术允许提供仅基于ComponentX
类名称的通用实现,从而“免费”获得ID的唯一性。
答案 1 :(得分:0)
一种方法是制作一些模板魔法,以防你可以修改IComponent
接口和类。类似的东西:
#include <iostream>
using namespace std;
typedef int ID_TYPE;
class IComponent
{
public:
IComponent() {}
template <class T>
ID_TYPE gclassId()
{
return T::classId();
}
virtual ID_TYPE getId() = 0;
};
class Comp1 : public IComponent
{
public:
Comp1() {}
virtual ID_TYPE getId() {return IComponent::gclassId<Comp1>();}
static ID_TYPE classId() {return 1; }
};
class Comp2 : public IComponent
{
public:
Comp2() {}
virtual ID_TYPE getId() {return IComponent::gclassId<Comp2>(); }
static ID_TYPE classId() {return 2;}
};
/*
class Comp3 : public IComponent
{
public:
Comp3() {}
virtual ID_TYPE getId() {return IComponent::gclassId<Comp3>(); }
};
*/
int main()
{
Comp1 a;
Comp2 b;
IComponent* t = new Comp2();
std::cout << a.getId() << t->getId();
delete t;
return 0;
}
这要求每个IComponent
派生类声明一个静态成员classId()
。如果取消注释Comp3
,则会出现编译错误。
通过修改它我的意思是你可以访问源代码。请忽略您的ID_TYPE的typedef,它可以是您想要的任何内容,只要您的虚拟函数通过gclassId
从IComponent
返回真实ID,而{{1}}依次变为强制性来自班级的静态方法。
答案 2 :(得分:0)
我不知道有什么方法可以强制派生类实现一个成员,除非通过纯虚方法。
我建议只使用纯虚拟或类似的文档来指示ID应该是类实现的唯一,而不是类实例。在理想的世界中,您应该能够依靠派生类的开发人员来阅读方法的文档,以了解它需要返回静态标识符而不是实例标识符。无论如何,你必须依靠它们来正确实现其他纯虚方法。