C++如何重载全局new operator为不同类类型分配对应内存池?
解答
你期望的直接在全局operator new中获取调用方类类型的需求,标准C++没有提供原生支持,无法直接实现。
全局operator new的唯一入参是待分配的内存字节数,没有携带任何调用方的类型元数据,运行时无法直接获取调用new表达式的类的类型信息。你示例中classname(caller)的逻辑没有标准实现可以支撑。
针对你的场景,可以根据实际约束选择以下可行方案:
方案1:重载目标类的类作用域operator new(最优解,可修改类定义时首选)
如果可以调整目标类的源码,或者可以通过继承封装第三方库的目标类,直接为每个需要定制内存分配的类重载内部的静态operator new和operator delete即可,编译器会自动在对应类实例化时调用专属的分配逻辑,不需要额外做类型判断:
// 以BigString类为例 class BigString { public: // 重载类专属new运算符 static void* operator new(std::size_t count) { return bigStringPool.alloc(count); } // 配对重载类专属delete运算符 static void operator delete(void* ptr, std::size_t count) { bigStringPool.free(ptr); } // 类原有其他成员定义... };
该方案不需要修改任何new BigString/delete ptr的调用代码,适配成本最低,稳定性最高。
方案2:宏替换new调用(无法修改类定义,但可调整调用代码时适用)
如果第三方库的类定义无法修改,但你可以改动所有实例化目标类的代码,可以通过自定义宏传递类型信息,绑定对应内存池:
// 先实现模板特化,关联不同类和对应的内存池 template<typename T> MemoryPool& get_memory_pool(); template<> MemoryPool& get_memory_pool<BigString>() { return bigStringPool; } template<> MemoryPool& get_memory_pool<4DVector>() { return vec4dPool; } // 定义自定义分配宏 #define POOL_NEW(T) new (get_memory_pool<T>()) T
使用时将原有new BigString()的调用替换为POOL_NEW(BigString)即可。
方案3:基于分配大小匹配(不推荐,仅做兜底)
如果既不能修改类定义,也不能调整调用代码,且你需要定制的目标类的实例大小全局唯一(没有其他类和它们大小相同,也没有继承派生场景),可以在全局operator new中通过分配的字节数间接匹配对应内存池:
void* operator new(std::size_t count) { if (count == sizeof(BigString)) { return bigStringPool.alloc(count); } else if (count == sizeof(4DVector)) { return vec4dPool.alloc(count); } return malloc(count); }
该方案局限性极强,一旦出现相同大小的其他类、或者目标类被继承派生,就会出现内存分配错误,生产环境需谨慎使用。
内容的提问来源于stack exchange,提问作者b20000
相关产品推荐
相关产品推荐

