2

我想要一个class T只能在整个程序中生成 1 个实例的实例。

现在我知道了,std::unique_ptr但有两个问题:

  • 它仅限于一个范围(但这不是一个大问题......)
  • 它需要显式使用,这意味着它不是类或类型的一部分,它只是和处理程序和一个特殊的指针,但它不会修改我的类的设计。

现在我想class T设计一种方式,即使错误地用户可以在同一个程序中声明 2 个实例,我也不能依赖我的用户将声明一个std::unique_ptrfor的事实,T因为我想通过设计来解决这个问题。

现在我只是在考虑如何以unique_ptr一种优雅的方式隐式使用 an ,问题是我目前没有任何线索。

另一种方法是检查这个类是否由 an 处理,unique_ptr但这种检查会使我在性能方面失去优势。

因为只有 1 个实例非常重要,所以在我的情况下我只看到 2 个选项:1)试图通过设计解决这个问题 2)在编译时使用某种检查/宏抛出错误。

我知道这看起来微不足道,但从设计方法来看,至少对我来说不是,所以请帮忙。

4

3 回答 3

4

您正在寻找的是所谓的单例模式,虽然它被许多人(包括我自己)广泛认为是一种反模式,但我仍将向您展示构建它所需的基本元素。

基本上你需要做的是提供三件事:

  1. 一种static“获取”唯一实例的方法
  2. private构造函数,因此没有人可以实例化它
  3. main(可选)在开始之前创建唯一实例的方法

这是基本代码:

class Singleton
{
public:
  Singleton&  get() 
  { 
    static Singleton me_;
    return me_;
  }
private:
  Singleton() {};
};

我留给你去发现如何实现上面的#3,以及为什么你不应该首先使用单例——有很多原因。

于 2012-10-08T19:35:18.563 回答
3

这通常被称为单例。

http://en.wikipedia.org/wiki/Singleton_pattern

C++ 中的典型技巧是拥有一个通过引用返回单例实例的函数,并将构造函数设为私有。

就像是:

#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 文件中。

于 2012-10-08T19:32:44.773 回答
2

你至少可以拥有

 static int count;
 assert(count == 0);
 count++;

在单例类的构造函数中。这并不能确保在编译时您的类是单例的,但至少它会在运行时检查它。

您还可以将构造函数设为私有,并有一个静态成员函数返回(一次)指向您的实例的指针,可能类似于

 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;
    }
 };
于 2012-10-08T19:31:07.397 回答