设计一个只有一个可能的实例(C++)的类/类型
Design a class/type with only 1 possible instance - C++
我想要一个class T
,它在整个程序中只能生成一个实例。
现在我知道了std::unique_ptr
,但有两个问题:
- 它被限制在一个范围内(但这不是一个大问题…)
- 它需要显式使用,这意味着它不是类或类型的一部分,它只是一个处理程序和一个特殊的指针,但它不会修改我的类的设计
现在,我希望class T
的设计方式即使是错误的,用户也可以在同一程序中声明两个实例,并且我不能依赖于我的用户将为T
声明std::unique_ptr
的事实,因为我想通过设计来解决这个问题。
现在我只是在想如何以优雅的方式隐含地使用unique_ptr
,问题是我现在没有任何线索。
另一种方法是检查这个类是否由unique_ptr
处理,但这种检查会使我在性能方面失去优势。
由于只有一个实例真的很重要,所以在我的情况下,我只看到两个选项:1)试图通过设计解决这个问题2)在编译时使用某种检查/宏抛出错误。
我知道这看起来微不足道,但从设计方法来看,至少对我来说不是,所以请帮忙。
您正在寻找的被称为Singleton模式,虽然它被许多人(包括我自己)广泛认为是一种反模式,但我仍将向您展示构建一个模式所需的基本元素。
基本上,你需要做的是提供三件事:
- 一个"获取"唯一实例的
static
方法 private
构造函数,因此没有人可以实例化它- (可选)在
main
启动之前创建唯一实例的方法
以下是基本代码:
class Singleton
{
public:
Singleton& get()
{
static Singleton me_;
return me_;
}
private:
Singleton() {};
};
我让您来了解如何实现上面的#3,以及为什么不应该首先使用Singleton——原因有很多。
这通常被称为Singleton。
请参阅http://en.wikipedia.org/wiki/Singleton_pattern
C++中的典型技巧是使用一个函数,该函数通过引用返回singleton实例,并使构造函数私有。
类似于:
#include <iostream>
using namespace std;
class Foo
{
private:
Foo() : a(3) { a++; }
static Foo singleton;
int a;
public:
static Foo& getFoo() { return singleton; }
void doStuff() { cout<<"My a is: "<<a<<endl; }
};
Foo Foo::singleton;
int main(int argc, char** argv)
{
Foo::getFoo().doStuff();
Foo &foo = Foo::getFoo();
foo.doStuff();
//uncomment below to cause compile error
//Foo foo2;
}
请注意,在实际代码中,您将把它拆分为一个标头和一个cpp文件。在这种情况下,
Foo Foo::singleton;
零件必须放在cpp文件中。
您至少可以拥有
static int count;
assert(count == 0);
count++;
在singleton类的构造函数中。这并不能确保在编译时您的类是单例的,但至少它在运行时会检查这一点。
您也可以将构造函数设为私有的,并让一个静态成员函数(一次)返回一个指向实例的指针,可能类似于
class Singleton {
private:
Singleton() {
static int count;
assert(count == 0);
count++;
};
Singleton(Singleton&) = delete;
public:
static Singleton* the_instance() {
static Singleton* it;
if (!it) it = new Singleton();
return it;
}
};
- 从C++实例化QML
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 我收到以下错误:抛出'std::bad_alloc'实例后终止调用
- 建议在运行时将带有类实例的列表从c++导入qml
- 约束和显式模板实例化
- 通过实例理解std::move及其目的
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 正在生成未知类实例
- 从DLL中删除类的实例
- 在std::vector上存储带有模板的类实例
- 为什么创建友元类的实例会导致"undefined reference to"错误?