【发布时间】:2012-10-26 06:58:00
【问题描述】:
我使用recursive template idiom 在工厂中自动注册基类的所有子类。但是,在我的设计中,子类必须将基类作为朋友类。由于我的基类的构造函数应该是私有的,以避免通过工厂以外的方式实例化此类。
总体目标是工厂的注册在 BaseSolver 中完成,并且 ChildClasses 不能通过工厂以外的方式实例化。
这是我的基类的代码,它自动在 SolverFactory 中注册所有子类。
template<class T>
struct BaseSolver: AbstractSolver
{
protected:
BaseSolver()
{
reg=reg;//force specialization
}
virtual ~BaseSolver(){}
/**
* create Static constructor.
*/
static AbstractSolver* create()
{
return new T;
}
static bool reg;
/**
* init Registers the class in the Solver Factory
*/
static bool init()
{
SolverFactory::instance().registerType(T::name, BaseSolver::create);
return true;
}
};
template<class T>
bool BaseSolver<T>::reg = BaseSolver<T>::init();
这里是我的子类的头文件:
class SolverD2Q5 : public BaseSolver<SolverD2Q5>{
private:
//how can I avoid this?
friend class BaseSolver;
SolverD2Q5();
static const std::string name;
}
这很好用。但是我真的不喜欢将 BaseSolver 添加为友元类,但是我不希望构造函数和静态成员名称是公开的。
是否有更优雅的解决方案或更好的布局来避免这种情况?
【问题讨论】:
-
为什么 BaseSolver 需要成为朋友类?你能把
friend class T添加到 BaseSolver 吗? -
这应该如何帮助我不想访问 BaseSolver 中的私有方法,但 BaseSolver 应该访问 Solver 的私有成员。
-
我喜欢这种设计。为什么
friend声明是个问题? -
将
private替换为SolverD2Q5中的protected仍然不公开,因此将BaseSolver中的T替换为派生自@987654331 的包装类@解决问题。我之前的回答只是给了一个提示。现在我添加了一个完整的例子。我看不出它不是一个解决方案,甚至不是侵入性的。而且它不会在可执行文件中创建额外的代码。
标签: c++ templates design-patterns idioms crtp