Класс ObjectInfo — это диагностический класс, предназначенный для отслеживания статистических данных, таких как время жизни и количество объектов. Определенный класс наследуется от ObjectInfo, как показано. Член этого конкретного класса затем объявляется в теле профилированного класса.
Хотя решение работает, его трудно поддерживать, так как оно требует, чтобы класс профилирования был синхронизирован с профилированным классом, поскольку имя класса используется для идентификации последующего. Также было бы сложно расширить класс профилирования для сбора различной информации, такой как размер объекта.
Предложите лучшее решение, где зависимости между профилируемым и профилирующим классами минимальны.
Можно ли реализовать проверку, которая бы определяла, был ли объект профилированного класса создан в стеке или куче?
— 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;
}
— Шаблон использования —
struct _AInfo : public ObjectInfo {
_AInfo() : ObjectInfo("_A") {}
};
struct _A {
_AInfo m_info;
};
Первоначально я думал, что этот вопрос задает вопрос об использовании техники отражения C ++ для сбора информации во время выполнения. Тем не менее, я не знаю, есть ли способ измерить время жизни объектов с помощью отражения C ++. Фурхтер, можете ли вы считать, что отражение в C ++ — это метод, который уменьшает зависимости между классами профилирования и профилирования?
Это может отслеживать создание стека и кучи объектов
#include <iostream>
template <class CRTP>
struct AllocationTracker
{
AllocationTracker()
{
++totalCreated;
}
void* operator new(size_t sz)
{
++heapCreated;
return ::operator new(sz);
}
static int totalCreated;
static int heapCreated;
};
template <class CRTP>
int AllocationTracker<CRTP>::totalCreated;
template <class CRTP>
int AllocationTracker<CRTP>::heapCreated;
class Derived : public AllocationTracker<Derived>
{
};
int main()
{
using namespace std;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 0/0
Derived dStack;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 0/1
Derived* dHeap = new Derived;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 1/2
}
При этом используется CRTP, который Бартек упомянул в комментариях к вашему вопросу. Это позволяет нам отслеживать каждый производный тип отдельно. Это также оборачивает стандарт new
для базового класса, который наследуется производными классами, что позволяет нам отслеживать выделения кучи. Таким образом, мы знаем, сколько экземпляров создано и сколько в куче, и мы можем сделать вывод, что остальные были в стеке (если вы не используете пулы объектов или некоторые другие более экзотические стратегии распределения в вашей программе).
Других решений пока нет …