AMC*_*der 15 c++ design-patterns idioms
我想知道是否存在自动注册类类型的设计模式或习惯用语.或者更简单,我可以通过简单地扩展基类来强制一个方法来调用类吗?
例如,假设我有一个基类Animal和扩展类Tiger和Dog,和我有打印出扩展的所有类的辅助功能Animal.
所以我可以这样:
struct AnimalManager
{
static std::vector<std::string> names;
static void registerAnimal(std::string name) {
//if not already registered
names.push_back(name); }
};
struct Animal
{
virtual std::string name() = 0;
void registerAnimal() { AnimalManager::registerAnimal(name()); }
};
struct Tiger : Animal
{
virtual std::string name() { return "Tiger"; }
};
Run Code Online (Sandbox Code Playgroud)
基本上我会这样做:
Tiger t;
t.registerAnimal();
Run Code Online (Sandbox Code Playgroud)
这也可以用于static函数.是否有任何模式(如奇怪的递归模板)或类似的东西可以帮助我实现这一点,而无需显式调用该registerAnimal方法.
我希望class Animal将来可以扩展,其他人可能会忘记打电话register,我正在寻找方法来防止这种情况,除了记录这一点(无论如何).
PS这只是一个例子,我实际上并没有实施动物.
Luc*_*ore 16
你确实可以使用奇怪的递归模板习语来做到这一点.它不需要扩展无法由编译器强制执行的类的任何人:
template<class T>
struct Animal
{
Animal()
{
reg; //force specialization
}
virtual std::string name() = 0;
static bool reg;
static bool init()
{
T t;
AnimalManager::registerAnimal(t.name());
return true;
}
};
template<class T>
bool Animal<T>::reg = Animal<T>::init();
struct Tiger : Animal<Tiger>
{
virtual std::string name() { return "Tiger"; }
};
Run Code Online (Sandbox Code Playgroud)
在此代码中,只有Animal在专门化的情况下才能进行扩展.构造函数强制初始化static成员reg,然后调用register方法.
编辑:正如@David Hammen在评论中指出的那样,你将无法拥有一组Animal对象.但是,这可以通过使用模板继承的非模板类并将其用作基类来轻松解决,并且仅使用模板进行扩展.
如果你坚持要注册每一只动物,为什么不做name一个Animal构造函数的参数.然后你可以把注册问题放到Animal构造函数中,每个派生都必须传递有效的名称和注册:
struct Animal
{
Animal(std::string name){ AnimalManager::registerAnimal(name);}
}
struct Tiger : Animal
{
Tiger():Animal("Tiger"){}
};
Run Code Online (Sandbox Code Playgroud)