是否可以强制一个类只由singleton实例化



当我用C++11编程时,我通常使用Singleton设计模式。以下是我如何设计我的Singleton:

template<typename T>
class Singleton {
private:
Singleton() = default;
~Singleton() = default;
public:
static T * GetInstance() {
static T t;
return &t;
}
Singleton(const Singleton &) = delete;
Singleton(Singleton &&) = delete;
Singleton & operator=(const Singleton &) = delete;
Singleton & operator=(Singleton &&) = delete;
};

然后,我们可以定义任何我们想要的类,比如class Test{};Singleton<Test>::GetInstance();将生成一个对象。

一切都很好。

然而,今天我认为class Test{};可以摆脱这种限制。我的意思是,尽管我定义了类Singletion<T>,但其他开发人员可以定义他们的类,如Test,而不使用Singleton,因此如果他们愿意,他们可以生成许多对象。但我想要的是,如果您决定定义一个类,它应该是singleton的,那么您不能通过调用构造函数来生成对象,而只能通过调用Singleton<Test>::GetInstance()来生成对象。

总之,我想得到这个:

Test t;  // compile error
Test *p = Singleton<Test>::GetInstance(); // OK

为此,我尝试了一些棘手的方法,例如,我让类Test继承Singleton<Test>:

class Test : public Singleton<Test> {
public:
Test() : Singleton<Test>() {}
};

因此,如果您正在定义一个类,它应该是singleton,那么您继承了类Singleton,现在您的类不能通过调用构造函数生成任何其他对象。但它不起作用,因为Singleton的构造函数是私有的。但如果我把friend T;写在Singleton类中,Test t;就合法了。。。

我似乎不能仅仅通过Singleton来强迫类用户构造对象。

有人能帮我吗?或者告诉我我正在做一些不可能的事情。。。

您可以使用CRTP模式来实现此

template <class T>
class Singleton {
public:
Singleton& operator = (const Singleton&) = delete;
Singleton& operator = (Singleton&&)      = delete;
static T& get_instance() {
if(!instance)
instance = new T_Instance;
return *instance;
}
protected:
Singleton() {}
private:
struct T_Instance : public T {
T_Instance() : T() {}
};
static inline T* instance = nullptr;
};
class Example : public Singleton<Example> {
protected:
Example() {}
};
int main()
{
auto& test = Example::get_instance();
Example e; // this will give you error
}

最新更新