Reputation: 2048
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
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
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
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