ObjectInfo class is a diagnostic class intended to track statistical data such as life time and number of objects. A specific class inherits from ObjectInfo as shown. A member of that specific class is then declared in the body of a profiled class.
Although the solution works it is hard to maintain as it requires the profiling class to be keep in sync with the profiled class as the class name is used to identify the later. It would also be hard to extend the profiling class to gather different information such as the size of object.
Propose a better solution where the dependencies between the profiled and profiling classes are minimal.
Is it possible to implement a check that would determine if the object of the profiled class was created on stack or heap?
-- ObjectInfo.h --
#pragma once
class ObjectInfo
{
public:
ObjectInfo(const char* objectName);
virtual ~ObjectInfo(void);
private:
static int m_counter;
int m_objectNumber;
const char* m_className;
};
-- ObjectInfo.cpp --
#include "StdAfx.h"
#include "ObjectInfo.h"
#include <iostream>
#include "TimePrinter.h"
using namespace std;
int ObjectInfo::m_counter = 0;
ObjectInfo::ObjectInfo(const char* name) :
m_className(name)
{
m_objectNumber = ++m_counter;
cout << "Object: " << m_className << "# " << m_objectNumber << " created @ " <<
TimePrinter()<< endl;
}
ObjectInfo::~ObjectInfo(void)
{
cout << "Object: " << m_className << "# " << m_objectNumber << " destroyed @ " <<
TimePrinter() << endl;
}
-- The use pattern --
struct _AInfo : public ObjectInfo {
_AInfo() : ObjectInfo("_A") {}
};
struct _A {
_AInfo m_info;
};
I originally thought this question is asking about using C++ reflection technique to gather the runtime information. However, I don't know if there is a way to measure the lifetime of objects using C++ reflection. Furhter, can you consider C++ reflection is a technique that reduces the dependencies between the profiled and profiling classes ?
This can track stack vs. heap object creations
This uses the CRTP that Bartek brought up in the comments on your question. This lets us track each derived type separately. It also wraps the standard
new
for the base class, which is inherited by derived classes, which allows us to track heap allocations. So we know how many instances are created, and how many on the heap, and we can infer that the rest were on the stack (unless you're using object pools or some other more exotic allocation strategies in your program).