The Light Spark
The Light Spark

Reputation: 504

How to make an Abstract class into a Singleton Object?

What the case is about: The problem stands like this- In order to make my program cross-platform, I have done an abstraction layer for the operations performed by the operating system. There is an abstract base class, called SystemComponent which looks something like this:

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

This is then inherited by another OS specific class, say for Windows its WindowsSystemComponent:

#ifdef _WIN23

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

#endif

This WindowsSystemComponent then impliments the OS specific functions.

To create a System component in Windows, I do this:

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

where framework makes calls to the OS functions specified in SystemComponent, and passes the pointer to whatsoever sub classes needs it.

What is needed: I would like to remove the passing of pointers, and make the SystemComponent class and the OS specific Functions implimentations acsessible to each object which wants to use them. Best way to do this was to make it a Singleton, but whin I try to do something like

virtual static SystemComponent* Instance() { /*...*/ };

inside the SystemComponent class, which is abstract, i get a compiler error, saying such a thing is not allowed.

How then, should I go about it?

Upvotes: 0

Views: 1257

Answers (4)

R Sahu
R Sahu

Reputation: 206607

Another way to deal with this is to emulate the notion of a singleton but let a derived class set the singleton to be used.

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;

When using WIN32, make sure WindowsSytemComponent is a singleton and set the instance in the base class at initialization time.

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

When using another platform, do the similar thing.

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

Upvotes: 3

Laura Maftei
Laura Maftei

Reputation: 1863

You won't be able to instantiate a class that is abstract. The singleton pattern restricts the instantiation of a class to one object. This is in conflict with the previous constraint. You could better think of using the abstract factory pattern

Upvotes: 1

AllenKll
AllenKll

Reputation: 1056

This can't be done the way you are proposing. But What I think could solve your problem would be use of the factory pattern. Wikipedia

You could do something like this:

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;
   }
};

Upvotes: 1

antlersoft
antlersoft

Reputation: 14786

You can't have a virtual static method, but the Instance method doesn't need to be virtual-- it just needs to create the right kind of SystemComponent for the platform you are running on. You just need to take the code you are using now to create the SystemComponent instance for the platform and put it in the Instance method.

Upvotes: 4

Related Questions