如何在基类中声明类似工厂的方法?

时间:2009-06-06 07:37:53

标签: c++ oop

我正在寻找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,因此它在后代类中是静态的
  • 如何在基类中调用后代构造函数

我认为按照我的计划方式克服这些问题可能是不可能的。如果是这样,我想就如何以任何其他方式解决它提出一些建议。


修改:代码中的一些细微更改。我错过了几个指针标记。

4 个答案:

答案 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";
         }
      }
};

如果我是你,我会重新开始,记住这个例子并记住以下内容:

  • factorioes不一定是单身人士
  • 工厂不一定是静态成员
  • 工厂不必是他们创建的层次结构的基类的成员
  • 工厂方法通常返回动态创建的对象
  • 工厂方法通常返回指针
  • 工厂方法需要一种方法来决定创建
  • 实例的类

我不明白为什么你的工厂需要反思,C ++在任何情况下都不会以有意义的方式支持。

答案 1 :(得分:2)

根据@Shakedown的回答,我会使用CRTP Basetemplate <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
}

它解决了您提出的问题:

  • 如何声明静态变量Instance,因此它在后代类中是静态的:它仅存在于SingletonDescendant类中。
  • 如何在基类中调用后代构造函数:使用新函数
  • 我必须在每个后代写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 }
};