Bob Jones
Bob Jones

Reputation: 2048

How to create single instance of base class

I have a class GenericRoot which has a number of classes that descend from it. I would like to create only a single instance of this class. I am familiar with this approach which I saw here:

    class genericRoot {
    private:
        genericRoot() {}

    public:
        static genericRoot &getInstance ();
    };

class Handler : public genericRoot {
}

However, this results in every Handler (and every other class that descends from Generic Root) to get two errors:

"error: within this context"

"error: genericRoot::genericRoot is private"

Is there a clean way to accomplish this?

Upvotes: 2

Views: 265

Answers (3)

Sam Kumar
Sam Kumar

Reputation: 508

If you really need to construct a subclass of genericRoot while keeping genericRoot's constructor private, you can declare each subclass to be a friend, as so:

class genericRoot {
private:
    genericRoot() {}
    friend class Handler;

public:
    static genericRoot &getInstance();
};

class Handler : public genericRoot {
};

I do, however, agree with the other answers that you should think carefully about why/whether you really need subclasses of a singleton class, as it is quite an odd situation.

Upvotes: 1

Peter Ruderman
Peter Ruderman

Reputation: 12485

The short answer is, no. The point of making the genericRoot constructor private is to prevent instances of it being created anywhere but in the getInstance factory method. When you create an instance of a genericRoot subclass, you implicitly create an instance of genericRoot too. (In fact, the new object is a genericRoot while the genericRoot constructor is running.)

So the design needs a bit of a rethink. I presume the idea here is to have all subclasses share some common state. If this is the case, then perhaps some private static state would make more sense than the singleton pattern. Something like:

class genericRoot
{
private:
  static SomeType private_state_;
protected:
  // whatever state accessors are needed for subclasses...
};

In lieu of a constructor for genericRoot, you would simply initialize the private state inside the corresponding cpp file:

SomeType genericRoot::private_state_ = InitializePrivateState();

Upvotes: 1

R Sahu
R Sahu

Reputation: 206607

Is there a clean way to accomplish this?

Sure. Make the default constructor of genericRoot a protected member function.

class genericRoot {
  protected:
    genericRoot() {}

  public:
    static genericRoot &getInstance ();
};

Having said that, I want to warn you that the need for an object of the base class does not sound right. It's a symptom of a design flaw somewhere. Think about your requirements a bit carefully and figure out whether there is any way to meet the requirements without creating an instance of the base class.

Upvotes: 1

Related Questions