I\'d like to be able to count instances of classes that belong in the same class hierarchy.
For example, let\'s say I have this:
class A;
class B: pu
Create the classes through a factory so the factory will be able to keep track of how many have been created.
Not as clean as just calling new on the class but it may do what you need.
Directly off my head:
Note: See Mykola's comments. This would print 4 for A, 3 for B and 2 for C i.e. it would count one instance of B as "one A and one B", and one C as "one A, one B and one C". Which is in a way true, but is not what the question asks for. In other words, my answer is wrong :)
A very crude way would be:
class A
{
public:
static int m_instanceCount;
A(bool derivedInstance = false)
{
if(! derivedInstance)
{
++m_instanceCount;
}
}
virtual ~A()
{
--m_instanceCount;
}
virtual int GetInstanceCount()
{
return m_instanceCount;
}
};
int A::m_instanceCount = 0;
class B : public A
{
public:
static int m_instanceCount;
B(bool derivedInstance = false): A(true)
{
if(! derivedInstance)
{
++m_instanceCount;
}
}
virtual ~B()
{
--m_instanceCount;
}
virtual int GetInstanceCount()
{
return m_instanceCount;
}
};
int B::m_instanceCount = 0;
class C : public B
{
public:
static int m_instanceCount;
C(): B(true) {++m_instanceCount;}
virtual ~C()
{
--m_instanceCount;
}
virtual int GetInstanceCount()
{
return m_instanceCount;
}
};
int C::m_instanceCount = 0;
void main(int argc,char *argv[])
{
A* p1 = new A;
B* p2 = new B;
C* p3 = new C;
C* p4 = new C;
A* p5 = new A;
delete p5;
std::cout<<p1->GetInstanceCount()<<"\n";
std::cout<<p2->GetInstanceCount()<<"\n";
std::cout<<p3->GetInstanceCount()<<"\n";
}
This is a simple counter I use each so often for debugging:
// counter.hpp
#ifndef COUNTER_HPP
#define COUNTER_HPP
template <typename T>
class Counter
{
public:
Counter( bool do_count = true ) : counted(do_count)
{ if ( counted ) get_count()++; }
~Counter() { if (counted) --count_; }
static unsigned long count() { return count_; }
static unsigned long& get_count() {
static unsigned long count=0;
return count;
}
private:
bool do_count;
};
#endif
The usage is simple, just inherit from it:
class BaseClass : public Counter<BaseClass>
{
public:
explicit BaseClass( bool do_count = true )
: Counter<BaseClass>( do_count )
{}
};
class DerivedClass : public BaseClass, Counter<DerivedClass>
{
public:
explicit DerivedClass( bool do_count = true )
: BaseClass(false), Counter<DerivedClass>(do_count)
{}
};
User code will call a parameterless constructor:
int main() {
BaseClass b; // will call Counter<BaseClass>(true)
DerivedClass d; // will call Counter<BaseClass>(false), Counter<DerivedClass>(true)
}
Use a static
member variable for each class.
struct A {
A() { mInstances++; }
~A() { mInstances--; }
static size_t mInstances;
static size_t GetInstancesCount() { return mInstances; }
};
size_t A::mInstances;
int main() {
A* a = new A;
A* aa = new A;
cout << A::GetInstancesCount() << endl;
delete a;
delete aa;
cout << A::GetInstancesCount() << endl;
return 0;
}
The current solutions all seem to count in constructors, and therefore also count in constructors of base type. (except Mykola, but that solution has an implicit conversion from bool - bad) This double-counting wasn't desired. The tricky part, though, is that during the construction of a derived type, the object temporary has intermediate base types. And with virtual base classes, this situation is even worse. In that case, the intermediate type isn't even well-defined.
Ignoring such transients, there are a few solutions to the double-counting:
The latter option (virtual base class) is probably the nicest; the compiler will enforce it's initialized once and only once, from the final ctor.
class counter {
template<typename T> struct perTypeCounter { static int count = 0; }
int* count; // Points to perTypeCounter<MostDerived>::count
protected:
template<typename MostDerived> counter(MostDerived*)
{
count = &perTypeCounter<MostDerived>::count;
++*count;
}
~counter() { --*count; }
};