如何将Abstract类转换为Singleton对象?

时间:2014-10-06 16:28:34

标签: c++ inheritance singleton

案例是什么: 问题就像这样 - 为了使我的程序跨平台,我为操作系统执行的操作做了一个抽象层。有一个名为SystemComponent的抽象基类,如下所示:

class SystemComponent{
public:
    //some functions related to operations for OS
    virtual WindowHandle CreateNewWindow(/*...*/) = 0;
    virtual void Show_Message(/*...*/)            = 0;
    //...
}

然后由另一个特定于操作系统的类继承,例如对于Windows WindowsSystemComponent

#ifdef _WIN23

class WindowsSystemComponent   :   SystemComponent{
public:
    virtual WindowHandle CreateNewWindow(/*...*/);
    virtual void Show_Message(/*...*/);
    //...
protected:
    //Windows specific things...
}

#endif

WindowsSystemComponent会影响操作系统特定的功能。

要在Windows中创建系统组件,我执行此操作:

WindowsSytemComponent* pWSystemComp = new WindowSystemComponent();
//...
//And the pass a pointer to this to the crossplatform code like this
pFrameWork->SetSystem((SystemComponent*)pWSystemComp);

其中框架调用SystemComponent中指定的OS函数,并将指针传递给子类所需的任何内容。

需要什么: 我想删除指针的传递,并使SystemComponent类和操作系统特定的函数实现对每个想要使用它们的对象都是可行的。最好的办法就是让它成为一个单身人士,但是当我尝试做像

这样的事情时
virtual static SystemComponent* Instance() { /*...*/ };

SystemComponent类中,这是抽象的,我得到编译器错误,说不允许这样的事情。

那么,我应该怎么做呢?

4 个答案:

答案 0 :(得分:4)

您不能拥有虚拟静态方法,但Instance方法不需要是虚拟的 - 它只需要为您运行的平台创建正确类型的SystemComponent。您只需要使用您现在使用的代码为平台创建SystemComponent实例并将其放在Instance方法中。

答案 1 :(得分:3)

另一种解决方法是模拟单例的概念,但让派生类设置要使用的单例。

class SystemComponent
{
  public:
    static SystemComponent* instance()
    {
       return theInstance_;
    }

    //some functions related to operations for OS
    virtual WindowHandle CreateNewWindow(/*...*/) = 0;
    virtual void Show_Message(/*...*/)            = 0;
    //...

  protected:

    static setInstance(SystemComponent* in)
    {
      theInstance = in;
    }
}

// Define the static member.
SystemComponent* SystemComponent::theInstance = nullptr;

使用WIN32时,请确保WindowsSytemComponent是单例,并在初始化时在基类中设置实例。

SystemComponent::setInstance(WindowsSytemComponent::instance());

使用其他平台时,请执行类似操作。

SystemComponent::setInstance(AnotherPlatformSytemComponent::instance());

答案 2 :(得分:1)

这不能按照你提议的方式完成。但我认为可以解决您的问题的方法是使用工厂模式。 Wikipedia

你可以这样做:

class SystemComponentFactory
{
   static SystemComponent* ptr = 0;

   static SystemComponent getSystemComponent()
   {
     if ( ptr == 0 )
     {
       if ( isWindows() )
          ptr = new WindowsSytemComponent();
       else if ( isLinux() )
          ptr = new XwindowsSystemComponent();
       ...
     }
     return ptr;
   }
};

答案 3 :(得分:1)

您无法实例化一个抽象的类。 单例模式将类的实例化限制为一个对象。这与先前的约束相冲突。您最好考虑使用abstract factory pattern