如何通过代码定位现有项目中指定类重载=运算符的调用位置
解决方案
方案1:C++20 无侵入实现(推荐)
借助C++20新增的std::source_location工具,可以直接在赋值运算符重载内获取调用方的完整位置信息,不需要修改原有调用代码:
#include <source_location> #include <fstream> #include <string> template<class T> class Tracker : public T { public: Tracker() = default; // 新增默认参数,调用方无需额外传参 T& operator=(const T& other, const std::source_location& loc = std::source_location::current()); }; template<class T> inline T& Tracker<T>::operator=(const T& other, const std::source_location& loc) { // 追加模式写入日志文件 std::ofstream log("track_record.log", std::ios::app); if (log.is_open()) { log << "=== 赋值操作记录 ===" << "\n"; log << "调用文件:" << loc.file_name() << "\n"; log << "调用行号:" << loc.line() << "\n"; // function_name返回完整函数签名,包含所属类、命名空间、参数信息 log << "调用函数:" << loc.function_name() << "\n\n"; } T::operator=(other); return *this; }
该方案完全不侵入原有业务代码,原有Tracker对象的赋值语句不需要任何修改即可自动记录所有调用信息。
方案2:旧标准兼容实现
如果编译器不支持C20,可以用编译器内置宏配合封装实现,兼容C11及更早版本:
#include <fstream> #include <string> // 跨编译器获取完整函数签名 #if defined(_MSC_VER) #define GET_FUNC_NAME __FUNCSIG__ #elif defined(__GNUC__) || defined(__clang__) #define GET_FUNC_NAME __PRETTY_FUNCTION__ #else #define GET_FUNC_NAME __func__ #endif template<class T> class Tracker : public T { public: Tracker() = default; T& assign(const T& other, const char* file, int line, const char* func); // 保留原有运算符重载,无日志场景可正常使用 T& operator=(const T& other) { return assign(other, "未知文件", 0, "未知函数"); } }; template<class T> inline T& Tracker<T>::assign(const T& other, const char* file, int line, const char* func) { std::ofstream log("track_record.log", std::ios::app); if (log.is_open()) { log << "=== 赋值操作记录 ===" << "\n"; log << "调用文件:" << file << "\n"; log << "调用行号:" << line << "\n"; log << "调用函数:" << func << "\n\n"; } T::operator=(other); return *this; } // 赋值操作封装宏,替换原有赋值语句即可记录位置 #define TRACK_ASSIGN(lhs, rhs) (lhs).assign(rhs, __FILE__, __LINE__, GET_FUNC_NAME)
使用时将原有trackerObj = value的语句替换为TRACK_ASSIGN(trackerObj, value)即可生成日志。
优化建议
- 频繁赋值的场景下,可以将日志文件句柄设为类静态成员,避免每次赋值都打开关闭文件,提升性能
- 如需监控对象完整生命周期,可以补充重载拷贝构造、移动构造、移动赋值、析构函数,添加对应日志,更方便排查内存问题
内容的提问来源于stack exchange,提问作者Brent Kingma
相关产品推荐
相关产品推荐

