案例是什么:
问题就像这样 - 为了使我的程序跨平台,我为操作系统执行的操作做了一个抽象层。有一个名为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
类中,这是抽象的,我得到编译器错误,说不允许这样的事情。
那么,我应该怎么做呢?
答案 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