我正在寻找C ++类设计问题的解决方案。我想要实现的是在基类中使用静态方法方法,它将返回后代类型的对象的实例。关键是,其中一些应该是单身人士。我在VCL中编写它所以有可能使用__properties
,但我更喜欢纯C ++解决方案。
class Base {
private:
static Base *Instance;
public:
static Base *New(void);
virtual bool isSingleton(void) = 0;
}
Base::Instance = NULL;
class First : public Base { // singleton descendant
public:
bool isSingleton(void) { return true; }
}
class Second : public Base { // normal descendant
public:
bool isSingleton(void) { return false; }
}
Base *Base::New(void) {
if (isSingleton())
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
else
return new /* descendant constructor */;
}
出现问题:
Instance
,因此它在后代类中是静态的我认为按照我的计划方式克服这些问题可能是不可能的。如果是这样,我想就如何以任何其他方式解决它提出一些建议。
修改:代码中的一些细微更改。我错过了几个指针标记。
答案 0 :(得分:4)
为了检查我们的术语是否同步 - 在我的书中,工厂类是一个类实例,可以创建其他类或类的实例。选择要创建的实例类型取决于工厂接收的输入,或至少基于它可以检查的内容。 Heres是一个非常简单的工厂:
class A { ~virtual A() {} };
class B : public A {};
class C : public A {};
class AFactory {
public:
A * Make( char c ) {
if ( c == 'B' ) {
return new B;
}
else if ( c == 'C' ) {
return new C;
}
else {
throw "bad type";
}
}
};
如果我是你,我会重新开始,记住这个例子并记住以下内容:
我不明白为什么你的工厂需要反思,C ++在任何情况下都不会以有意义的方式支持。
答案 1 :(得分:2)
根据@Shakedown的回答,我会使用CRTP Base
对template <class T>
class Base
{
public:
static std::auto_ptr<Base<T> > construct()
{
return new T();
}
};
class First : public Base<First>
{
};
class Second : public Base<Second>
{
};
的实际类型进行模板化。
construct
这很好,因为std::auto_ptr<First> first(First::construct());
std::auto_ptr<Second> second(Second::construct());
// do something with first and second...
现在再次成为静态成员。你会这样称呼:
{{1}}
答案 2 :(得分:1)
您可以创建Singleton类和NonSingleton类,并使所有后代继承其中一个。
class Base {
public:
static Base *New() = 0;
}
class SingletonDescendant: public Base {
public:
*Base::New() {
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
}
private:
static Base *Instance;
}
SingletonDescendant::Instance = NULL;
class NonSingletonDescendant: public Base {
public:
*Base::New() {
return new;
}
}
class First : public SingletonDescendant{ // singleton descendant
}
class Second : public NonSingletonDescendant{ // normal descendant
}
它解决了您提出的问题:
construct()
方法;我认为它是多余的,因为很明显它必须做什么:现在它只在SingletonDescendant和NonSingletonDescendant中。 答案 3 :(得分:0)
这样的事情怎么样:
class Base
{
public:
virtual Base construct() = 0;
};
class First : public Base
{
public:
Base construct(){ return First(); // or whatever constructor }
};
class Second : public Base
{
public:
Base construct(){ return Second(...); // constructor }
};