简体   繁体   English

如何限制一个类的实例数?

[英]How can I limit the number of instances of a class?

As an exercise, I wish to make a class that can't have more than N instances. 作为练习,我希望创建一个不能超过N个实例的类。 How can I do that? 我怎样才能做到这一点?

Suppose, for example, you want to limit number of connection to database so that no more than N users can connect at the same time. 例如,假设您要限制与数据库的连接数,以使最多只能有N个用户同时连接。 I understand how to make a singleton: 我了解如何制作单身人士:

class Singleton {

private:

    Singleton(const Singleton&);

    Singleton();

public :

    static Singleton Instance() {

         static Singleton p;

         if(!p) {

                p = new Singleton;

         }
};

But if there N > 1 objects, I need help. 但是如果N> 1个对象,我需要帮助。

First of all, why ? 首先, 为什么

Once we get that question out of the way, you already know how to make a class that allows for just one instance, I assume? 一旦我们解决了这个问题,我想您已经知道如何制作只允许一个实例的类了吗? Usually, you do that with a static instance and a private constructor (or some variation thereof). 通常,您使用静态实例和私有构造函数(或其某些变体)来执行此操作。 To generalise that to N instances, all you need to do is store a static array of instances. 要将其推广到N个实例,您需要做的就是存储实例的静态数组

Finally, seriously, WHY ? 最后,认真地, 为什么

Use a static variable that is called count for example. 例如,使用一个称为count的静态变量。 In the constructor just add one each time an object is created: 在构造函数中,每次创建一个对象时只需添加一个:

struct myclass
{
  myclass()
  {
    if(count == N) /*throw some exception!*/
    ++count;
  }
  ~myclass()
  {
    --count;
  }
private:
  static std::size_t count = 0;
};

The only purpose I can see for something like this is to create a pool of "workers" (or something similar). 我能看到的唯一目的是创建一个“工人”库(或类似的库)。 The best way to achieve this is to create two classes: one "WorkerPool" class and one "Worker" class. 实现此目的的最佳方法是创建两个类:一个“ WorkerPool”类和一个“ Worker”类。 Something like this: 像这样:

typedef boost::shared_ptr<Worker> WorkerPtr;

class Worker{
   // do the worker stuff here
}

class WorkerPool{
   public:
     const int MAX_WORKERS = 20;
     WorkerPool(){ for(int i=0;i<MAX_WORKERS;i++)
                        _pool.push_back(WorkerPtr(new Worker()) );
                  }

     WorkerPtr get(){
          if(_pool.size()>0) return _pool.pop_front();
          return WorkerPtr();
     }    

     void release(WorkerPtr w){
          return _pool.push_back(w);
     }    

     private:
       std::list<WorkerPtr> _pool;

}

It's just an example, you may do it differently (including making the WorkerPool a singleton, synchronizing get() instead of returning NULL, etc.) - but you get the picture. 这只是一个示例,您可以做不同的操作(包括使WorkerPool为单例,同步get()而不是返回NULL等)-但是您得到了图片。

First, a compiling and working version of the code "public" is: 首先,代码“ public”的编译工作版本为:

static Singleton*  Instance() {
  static Singleton *p;
  if(!p) { p = new Singleton; }
  return p;
}

For the sake of the exercise, you could modify to N instances by using 为了便于练习,您可以使用修改为N个实例

static Singleton* Instance(int n) {
  static Singleton *p[N];
  if(!p[n]) { p[n] = new Singleton; }
  return p[n];
}

Error checking omitted. 省略错误检查。

使用固定大小的数组?

Use a factory method for instance creation. 使用工厂方法创建实例。 Also have a static variable in the class to to keep track of number of instances in existence. 类中还具有一个static变量,以跟踪存在的实例数。 If the upper limit is hit you can trow an exception or return an already created object, depends on your design. 如果达到上限,则可以抛出异常或返回已经创建的对象,具体取决于您的设计。 To enable object creation only through the factory method you'll have to make the ctor private . 要仅通过工厂方法启用对象创建,必须将ctor设为private

除非该类将自身限制为N个实例100%有意义,否则您应该真正将该类包装到一个静态访问类中,该类几乎不会限制实例的数量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM