开发者

Limit the number of instances with the new keyword

I've been reading a lot of debates about whether the Singleton pattern is good/bad/ugly, and what should be used instead of it.

The common implementation requires an Instance() method that invokes a private constructor if the object has not yet been created.

My question doesn't really fit the Singleton pattern, but would it be possible to limit the number of instances of a class by overriding new? And if say we only want one instance, return the already created instance?

If this is pos开发者_开发知识库sible is it even a good idea?

The aim would be that in any class needing access to a class, one would simply declare a private member, which would be initialized the first time, and then referenced for the rest.

ClassA {
    MyClass classRef;
}

ClassB {
    MyClass classRef;
}

So if MyClassis limited to one instance, depending on the order of instancing, one of these objects will actually create a new MyClass, and the other will just obtain it's reference.


Objects can be allocated statically, on the stack, and within other objects. If you want just one instance, you need to disallow all of these somehow. Overloading operator new won't help you with this. Making the constructors private or protected will, but this will disable operator new for the users of the class as well.

Moreover, what operator new returns is not an object, but a block memory in which the object will be created. If you return an already allocated block, a constructor will be run over it each time operator new is called.


This sounds like a non-concurrent worker pool of some sort.

This can be a good idea when a large number of jobs are going to be executed by more than one service/driver and you want to implement throttling, or perhaps queue jobs to prevent swap file thrashing, or some other resource constraint.

Overriding new is probably not the right way to do it. Have the task farm be an object itself, and "allocate" tasks from there. The raw allocation of the task handle wrapper object should be free from such considerations.

And yes, singletons are ugly (or at least an ugly implementation of a good idea).


Overriding new won't work. First, it won't prevent additional instances on the stack or as static variables. Second, the operator new that you define only allocates memory; the constructor will still be called (with possibly disasterous effects if the singleton has mutable state).


You can limit the number of instantiations much more straightforwardly by keeping a counter as a static member variable:

template<unsigned int N>
class N_gleton {
  private:
    static int number_of_instances_;

  public:
    enum { MAX_NUMBER_OF_INSTANCES = N };

    N_gleton() {
      assert(number_of_instances_ < MAX_NUMBER_OF_INSTANCES);
      ++number_of_instances_;
    }
};

template<unsigned int N>
int N_gleton<N>::number_of_instances_ = 0;  // initial value
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜