如何实现C++类易用无继承冲突的日志器,支持自定义前缀和颜色
问题根因
你当前的c2类同时继承c1和logger,属于非虚基类的重复继承,会在c2实例中生成两个独立的logger子对象,调用log/error方法时会产生二义性冲突,两个子对象的前缀、id、日志历史也完全独立,不符合预期。
推荐方案(零继承冲突,改造成本最低)
放弃继承logger,改用「成员变量+using导入方法」的实现,完全满足你的所有需求:
- 保留类内直接调用
log("txt")/error("txt")的写法 - 不需要手动拼接类名前缀
- 每个类的日志配置(前缀、颜色、历史记录)完全独立
- 彻底规避多继承冲突
改造示例
原有logger类代码不需要做任何修改,仅修改业务类的定义即可:
// c1类定义 class c1 { public: c1(): m_logger("c1 log") {} // 导入日志方法到类作用域,直接调用即可 using m_logger::log; using m_logger::error; private: logger m_logger; // 其他c1的业务逻辑 }; // c2类继承c1 class c2 : public c1 { public: c2(): m_logger("c2 log", "#ff0000") {} // 支持自定义颜色 using m_logger::log; using m_logger::error; private: logger m_logger; // 其他c2的业务逻辑 };
如果需要叠加父类前缀,可在子类构造函数中调用m_logger.loggerAddPrefixAndSetColor("c1 log")即可。
备选方案(坚持用继承的实现)
如果一定要用继承的写法,可改为虚继承logger基类,避免重复生成基类实例:
// 所有派生类都虚继承logger class c1 : virtual public logger { public: c1(): logger("c1 log") {} }; class c2 : virtual public c1 { public: // 虚基类的构造仅由最顶层派生类调用,不会和父类的初始化冲突 c2(): logger("c2 log") { // 需要叠加父类前缀的话手动加即可 loggerAddPrefixAndSetColor("c1 log"); } };
原有代码bug修复
你当前的logger类存在两个小问题需要修正:
- 构造函数中没有调用
getId(),导致id永远为-1,上报到日志管理类时会异常,在所有logger构造函数末尾添加getId();即可 - 日志存储逻辑写反:
log()方法把日志存到了errorHistory,error()方法存到了logHistory,调整下对应变量即可。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

