tags:

views:

401

answers:

5

how to count the number of objects created in c++

pls explain with a simple example

+1  A: 

Number of objects for what? If you want to count the number of objects of a specific class, you can use a static counter. Something like below.. Increment counter on creation and decrement while destruction..

class A
{
  public:
    static int counter;
    A()
    {
      counter ++;
    }
    virtual ~A()
    {
      counter --;
    }
};

int A :: counter = 0;
bdhar
A: 

You could create a counter variable into the public: of your class (assuming here you're talking about counting objects from a class you created)

class Widget {
public:
    Widget() { ++count; }
    Widget(const Widget&) { ++count; }
    ~Widget() { --count; }

    static size_t howMany()
    { return count; }

private:
    static size_t count;
};
// obligatory definition of count. This
// goes in an implementation file
size_t Widget::count = 0;

Taken from ddj.com

Alex Marcotte
you should read the whole article from scott meyers to see that this solutions is not the best. At the end of the article he describes the template approach mentioned in the other posts.
Holger Kretzschmar
+15  A: 

Create template class with a static counter.

Each object in your application would then extend this template class.

When constructor is called increment static count (static variable is per class - shared by all objects of that class).

For example see Object Counter using Curiously recurring template pattern:

template <typename T>
struct counter
{
    counter()
    {
        objects_created++;
        objects_alive++;
    }

    virtual ~counter()
    {
        --objects_alive;
    }
    static int objects_created;
    static int objects_alive;
};
template <typename T> int counter<T>::objects_created( 0 );
template <typename T> int counter<T>::objects_alive( 0 );

class X : counter<X>
{
    // ...
};

class Y : counter<Y>
{
    // ...
};

Usage for completeness:

int main()
{
    X x1;

    {
        X x2;
        X x3;
        X x4;
        X x5;
        Y y1;
        Y y2;
    }   // objects gone

    Y y3;

    cout << "created: "
         << " X:" << counter<X>::object_created
         << " Y:" << counter<Y>::object_created
         << endl;

    cout << "alive: "
         << " X:" << counter<X>::object_alive
         << " Y:" << counter<Y>::object_alive
         << endl;
}

Output:

created:  X:5 Y:3
alive:  X:1 Y:1
stefanB
Hi. Nice approach. I never knew about that. Thanks!
bdhar
Some time ago I was doing some static polymorphism and bumped to this example, I really like it, and static polymorphism is cool as well ...
stefanB
Nice solution, I have a doubt though.. is it really necessary to make the destructor virtual in the class template when using CRTP? I am just worried about the slight size overhead caused by the v-tables..
Naveen
works without virtual destructor as well.
stefanB
its due to private inheritance since in this case derived class object is not base class one and compiler will not do implicit type conversion.
Ashish
is there any other reason for the private inheritance?
mizipzor
how does this handle.X x2;X x3 = x2;
Jagannath
I think there is no need to make destructor virtual and benefits of private inheritance are : 1. counter<X> *px = new X; // error no implicit conversion is allowed 2. delete px; // destructor not accessible
Ashish
struct inheritance is public by default, since it's not specified it's public not private, unlike class where the inheritance is public by default.
stefanB
Excellent example.
Thomas Matthews
Unfortunately, this example only counts the objects created that are derived from the template class.
Thomas Matthews
you could implement static count in each of your classes by hand, but this simplifies things a bit, you can add custom stuff in classes that need to do more ...
stefanB
+6  A: 
template <class T>
class Counter
{
  private:
      static int count = 0;
  public:
    Counter()
    {
       count++;
    }  
    Counter(const Counter &c)
    {
       count++;
    }   
    ~Counter()
    {
       count--;
    }    
    static int GetCount() {

         return count;
    }
}

class MyClass : private Counter<MyClass>
{
   public:
      using Counter<MyClass>::GetCount();
}

This technique is called CRTP

Ashish
@stefanB, This is the correct approach. You need to have copy constructor in Counter.
Jagannath
+1, stefanB's approach does not handle 'X x2; X x3 = x2;'. But you can't initialize count like that, since it's not const.
Samuel_xL
+2  A: 

You have to overload the new and delete operators to count memory allocations.

void * operator new (size_t size)
{
    void * p = malloc (size);
    num_allocations++;
    return p;
}

void operator delete (void * p)
{
    num_deletions++;
    free (p);
}
DevDevDev
I think new [] and delete [] also have to be overloaded if you want to track objects on heap .
Ashish
Yes you are correct Mac. I was just trying to get him started. You need to overload every variation of new that you are using.
DevDevDev