C++ 对象生命周期分析

标签 c++ design-patterns rtti

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;
};

-- 对象信息.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
}

这使用 Bartek 在对您的问题的评论中提出的 CRTP。这让我们可以分别跟踪每个派生类型。它还为基类包装了标准的 new,它由派生类继承,这使我们能够跟踪堆分配。所以我们知道创建了多少实例,有多少实例在堆上,我们可以推断其余实例在堆栈上(除非您在程序中使用对象池或其他一些更奇特的分配策略)。

关于C++ 对象生命周期分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15050622/

相关文章:

c++ - 虚拟异常类导致动态链接器错误

用于开发命令行的 C++ 库

c++ - 透视正确的纹理贴图; z距离计算可能错误

c++ - regex_match 不产生任何结果

javascript - 高级原型(prototype)函数

c# - 在 C# 中返回状态代码或复杂对象的理想方法是什么?

c# - 在此示例中如何避免破坏 LSP? C#

c++ - 存储有关对象类型的信息

c++ - 切换到非调试运行时/MT 导致链接错误

delphi - RTTI:如何获取声明为类属性的动态数组的值