C++中统计各类的实例数量

背景

游戏开发中,有时候需要知道某些类的实例数量,用于分析内存变化。
但是在已有大量class的情况下,不太可能去给每个类单独加一段统计代码。为了方便,我们最好是有一段通用的统计逻辑,其他类可以直接用上,类似python中的装饰器。

这里我们引入CRTP模板模式。

CRTP(Curiously Recurring Template Pattern,奇异递归模板模式)是C++中一种基于模板和继承的高级编程技巧,核心思想是通过将派生类自身作为模板参数传递给基类,实现编译时多态和代码复用。

实现


#include <iostream>
#include <typeinfo>
#include<unordered_map>

#define COUNT_OBJ

class StaticCountMap
{
protected:
	static std::unordered_map<const char*, int> mObjCount;
	StaticCountMap()
	{
	}

public:
	~StaticCountMap()
	{
	}
	static void printCount()
	{
		std::cout << "Object Count:" << std::endl;
		for (auto& it : mObjCount)
		{
			std::cout << "	" << it.first << ": " << it.second << std::endl;
		}
		std::cout << std::endl;
	}
};

std::unordered_map<const char*, int> StaticCountMap::mObjCount;

template<typename T>
class AutoCounter :public StaticCountMap
{
protected:
	AutoCounter()
	{
		auto clsName = typeid(*this).name();
		StaticCountMap::mObjCount[clsName]++;
	}

public:
	~AutoCounter()
	{
		auto clsName = typeid(*this).name();
		StaticCountMap::mObjCount[clsName]--;
		if (StaticCountMap::mObjCount[clsName] == 0)
		{
			StaticCountMap::mObjCount.erase(clsName);
		}
	}
};

class Derived : public AutoCounter<Derived>
{
public:
	Derived()
	{
	}
	~Derived()
	{
	}
};


class Derived2 : public AutoCounter<Derived2>
{
public:	
	Derived2()
	{
	}
	~Derived2()
	{
	}
};

#ifdef COUNT_OBJ
class ExistingClass :public AutoCounter<ExistingClass>
#else
class ExistingClass 
#endif
{
	//...
};

int main()
{

	Derived d;
	Derived2 d21, d22;
	ExistingClass e1, e2, e3;
	StaticCountMap::printCount();
	return 0;
}


posted on 2025-05-14 13:00  寒窗苦碼  阅读(16)  评论(0)    收藏  举报