我有一个稍微恶心的设置,我试图找出检修的好方法。保留子类的中心列表,但避免静态实例
我有一个class Fractal
与几个纯虚函数来做工作。每个实例也有一个人类可读的名字。我想要构建一个所有这些子类的菜单,以便用户可以在它们之间切换 - 但是,由于懒惰,我不想同时在源文件中定义每个实例,并在另一个实例中再次列出它们。换句话说,我想在运行时动态建立这个子类的列表。
我做了什么(有工作)至今是:
- 定义
class FractalRegistry
这是一个std::map<std::string,Fractal*>
(其中键是实例名称)的单封装, - 有基地
Fractal
构造函数通过名称向该注册表注册每个实例(并且为了完整性,基地~Fractal
注销它们), - 静态地实例化每个基类(使用其名称,这是一个构造函数参数)。
所以对于每一个新的分形我写这样的事情(转述):
class SomeFractal : public Fractal {
public:
SomeFractal(std::string name, std::string desc) : Fractal(name,desc) {}
virtual void work_function(...) { ... }
}
SomeFractal sf_instance("Some fractal", "This is some fractal or other");
和实例添加到由基类构造函数中央列表,所以我并不需要列出它自己。
但是,这会导致静态实例处于负载状态,如果将此代码移动到库中,这似乎会消失。 (是的,我可以添加一个可怕的空函数每个编译单元,所以我可以强制将其列入,或诉诸到链接弄虚作假如-Wl,--whole-archive
,但这些似乎并没有像正确答案,无论是。)
是有更好的方法?我想我正在寻找的是一种编写这些Fractal实现的方法 - 所有这些实现都有相同的接口,所以我认为基类的子类将是理想的 - 并且保留并填充它们的中央注册表,但不会离开我自己是静态实例的地雷。
我错过了什么? 我应该说我已经和C一起工作了很多年,但并没有真正的C++禅,所以很可能会有这样的工作能够做到让我面对我的工作......(如果我正在编写这个在C中,我会考虑编写一个二阶宏组合,它既声明了一些函数指针,又用它们和分形的名称和描述填充了一个表格,但这是一个更重要的事情,它看起来并不像适合C++)
编辑: 我所希望实现的是这使得它容易增加新的分形类型,并自动重新安排我的代码的一种优雅的方式填充他们的中心名单,但不迫使程序员创建每个分形的静态实例。
是那些子类应该是这样的单身?例如,你不希望用户能够实例化一个或者你想要什么?我无法弄清楚。 – Xeo 2011-05-28 23:54:48
我通常会放弃 - 无论使用哪种makefile技巧来构建和链接所有单个分形,还能够为注册每个分形的实例的函数生成源代码。从'main'中调用该函数,或者在库函数中调用该函数,或者从FractalRegistry的构造函数中调用该函数,或者从执行查找的函数调用该函数(当然,检查它当前还没有被调用)。 – 2011-05-28 23:58:19
是否可以以“黑匣子”的形式将2-3行延伸到您的问题(即输入和结果是什么)。你的问题不清楚。 – iammilind 2011-05-29 06:02:03