2

Given a class, I would like to limit the number of objects created from this class to a given number, say 4.

Is there a method to achieve this?

Mat
  • 202,337
  • 40
  • 393
  • 406
nitin_cherian
  • 6,405
  • 21
  • 76
  • 127
  • 1
    That depends. Do copies of instances count as new instances or are they fine? – Konrad Rudolph Jun 24 '12 at 15:50
  • 1
    You say object _creations_ rather than _instances_. If I create 4 instances, then delete one, should I be allowed to create another? You might want to think about thread safety, too. Notably, none of the answer below consider this (though it isn't a particularly complex extension. – Rook Jun 24 '12 at 16:33

2 Answers2

5

The basic idea is to count the number of created instances in some static variable. I would implement it like this. Simpler approaches exist, but this one has some advantages.

template<class T, int maxInstances>
class Counter {
protected:
    Counter() {
        if( ++noInstances() > maxInstances ) {
            throw logic_error( "Cannot create another instance" );
        }
    }

    int& noInstances() {
        static int noInstances = 0;
        return noInstances;
    }

    /* this can be uncommented to restrict the number of instances at given moment rather than creations
    ~Counter() {
        --noInstances();
    }
    */
};

class YourClass : Counter<YourClass, 4> {
}
unkulunkulu
  • 11,576
  • 2
  • 31
  • 49
  • 1
    As long as you're defining a template superclass, you might as well add a second template parameter for the max number of instances. I.e.: `template class Counter {...};` – Edward Loper Jun 24 '12 at 15:57
  • 1
    +1. But better to wrap the static member into an inline accessor function, to avoid the template definition in the source file. – Potatoswatter Jun 24 '12 at 16:04
  • @EdwardLoper, it was kind of a compliment to Luchian Grigore's answer, where he preserves that constant from the question, found it funny, will edit, thanks – unkulunkulu Jun 24 '12 at 19:55
3

You're looking for the instance manager pattern. Basically what you do is restrict instantiations of that class to a manager class.

class A
{
private: //redundant
   friend class AManager;
   A();
};

class AManager
{
   static int noInstances; //initialize to 0
public:
   A* createA()
   {
      if ( noInstances < 4 )
      {
         ++noInstances;
         return new A;
      }
      return NULL; //or throw exception
   }
};

A shorter way is throwing an exception from the constructor, but that can be hard to get right:

class A
{
public:
   A()
   {
       static int count = 0;
       ++count;
       if ( count >= 4 )
       {
           throw TooManyInstances();
       }
   }
};
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625