【问题标题】:How to create single instance of base class如何创建基类的单个实例
【发布时间】:2018-11-28 00:01:52
【问题描述】:
我有一个类 GenericRoot,它有许多从它派生的类。我只想创建这个类的一个实例。我对这种方法很熟悉,我看到here:
class genericRoot {
private:
genericRoot() {}
public:
static genericRoot &getInstance ();
};
class Handler : public genericRoot {
}
但是,这会导致每个 Handler(以及从 Generic Root 派生的每个其他类)都会出现两个错误:
“错误:在此上下文中”
“错误:genericRoot::genericRoot 是私有的”
有没有干净的方法来完成这个?
【问题讨论】:
标签:
c++
constructor
singleton
【解决方案1】:
有没有干净的方法来完成这个?
当然。将genericRoot 的默认构造函数设为protected 成员函数。
class genericRoot {
protected:
genericRoot() {}
public:
static genericRoot &getInstance ();
};
话虽如此,我想警告您,对基类对象的需求听起来并不正确。这是某处设计缺陷的症状。仔细考虑您的需求,并弄清楚是否有任何方法可以在不创建基类实例的情况下满足需求。
【解决方案2】:
简短的回答是,不。将genericRoot 构造函数设为私有的目的是防止在getInstance 工厂方法之外的任何地方创建它的实例。当你创建一个genericRoot 子类的实例时,你也隐式地创建了一个genericRoot 的实例。 (事实上,当genericRoot 构造函数正在运行时,新对象是一个genericRoot。)
所以设计需要重新考虑。我认为这里的想法是让所有子类共享一些共同的状态。如果是这种情况,那么某些私有静态状态可能比单例模式更有意义。比如:
class genericRoot
{
private:
static SomeType private_state_;
protected:
// whatever state accessors are needed for subclasses...
};
代替genericRoot 的构造函数,您只需在相应的cpp 文件中初始化私有状态:
SomeType genericRoot::private_state_ = InitializePrivateState();
【解决方案3】:
如果您确实需要构造genericRoot 的子类同时保持genericRoot 的构造函数私有,您可以将每个子类声明为friend,如下所示:
class genericRoot {
private:
genericRoot() {}
friend class Handler;
public:
static genericRoot &getInstance();
};
class Handler : public genericRoot {
};
但是,我同意其他答案,您应该仔细考虑为什么/是否真的需要单例类的子类,因为这是一种非常奇怪的情况。