is there any way to make all derived classes count their instances?How (write code in one of C++, C#, Java)?
Imagine I\'ve got access to the root class (e.g. object), an
In Java you can use a global Multiset
:
import com.google.common.collect.ConcurrentHashMultiset;
public abstract class InstanceCounted {
protected InstanceCounted() {
COUNT_MAP.add(this.getClass());
}
protected static final ConcurrentHashMultiset> COUNT_MAP =
ConcurrentHashMultiset.create();
}
Alternatively you can use a Map
if you don't want the dependency on guava.
Note: this only tracks instance creation, not garbage collection, so the count will never decrease. You can also track collection using PhantomReference
s if you are willing to take a performance hit:
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
public abstract class InstanceCounted {
public static int getInstanceCount(Class extends InstanceCounted> clazz) {
reap();
return INSTANCES.get(clazz).size();
}
protected InstanceCounted() {
reap();
INSTANCES.put(getClass(), new CountingReference(this));
}
static final Multimap, CountingReference> INSTANCES =
Multimaps.synchronizedSetMultimap(HashMultimap., CountingReference>create());
static final ReferenceQueue QUEUE =
new ReferenceQueue();
private static void reap() {
Reference extends InstanceCounted> ref;
while ((ref = QUEUE.poll()) != null) {
((CountingReference) ref).clear();
}
}
private static class CountingReference extends PhantomReference {
public void clear() {
super.clear();
INSTANCES.remove(clazz, this);
}
CountingReference(InstanceCounted instance) {
super(instance, QUEUE);
this.clazz = instance.getClass();
}
private final Class extends InstanceCounted> clazz;
}
}