C++模板装饰器:如何在静态方法中修改类成员属性?
问题解决方案
你当前的代码存在两个核心问题:
- 静态成员函数
warn没有this指针,无法直接访问类的非静态成员val; - 现有装饰器仅支持普通函数/静态成员函数,无法关联类实例以访问非静态成员。
以下是针对需求的修改方案:
1. 调整装饰器以支持成员函数
修改装饰器模板,让它同时持有类实例指针和成员函数指针,这样就能在装饰逻辑中访问实例的成员:
#include <cstdio> #include <chrono> #include <ctime> template <typename T, typename Func> struct Decorator { // 持有类实例指针和成员函数指针 T* instance; Func member_func; template <typename... Args> auto operator()(Args... args) { // 打印当前时间(执行前) auto now = std::chrono::system_clock::now(); std::time_t now_time = std::chrono::system_clock::to_time_t(now); printf("Before warn execution, current time: %s", std::ctime(&now_time)); // 调用目标成员函数 (instance->*member_func)(args...); printf("After warn execution\n"); } };
2. 修改Logger类适配装饰器
将warn改为非静态成员函数(这样它能直接访问val),同时调整装饰器实例的初始化:
class Logger{ private: int val= 0; // 改为非静态成员函数,可直接访问val void warn(char * str, char * ptr){ printf("Inside warn()\n"); printf("%s %s\n", str, ptr); val++; // 每次调用warn时自增val } void info(){printf("Inside info()\n");} // 让装饰器可以访问私有成员(若需在装饰器中操作val则保留,否则可删除) template <typename T, typename Func> friend struct Decorator; public: // 初始化装饰器,传入当前实例指针和warn成员函数指针 Decorator<Logger, decltype(&Logger::warn)> decoratedWarn{this, &Logger::warn}; int get_val(){return val;} };
3. 主函数调用逻辑不变
int main(){ char str[6] = "hello"; char ptr[6] = "world"; Logger log; // 调用装饰后的warn log.decoratedWarn(str, ptr); printf("val after warn: %d\n", log.get_val()); // 输出1 // 再次调用验证自增 log.decoratedWarn(str, ptr); printf("val after second warn: %d\n", log.get_val()); // 输出2 return 0; }
关键改动说明
- 静态转非静态:将
warn改为非静态成员函数,使其拥有this指针,从而直接访问类的非静态成员val,实现每次调用自增的需求。 - 装饰器扩展:让装饰器持有类实例指针,既能调用成员函数,也能在需要时直接操作实例的成员(若业务逻辑需在装饰器中处理而非
warn内)。 - 时间打印:使用
<chrono>和<ctime>库获取并格式化当前系统时间,在warn执行前输出。
内容的提问来源于stack exchange,提问作者Weed Cookie
相关产品推荐
相关产品推荐

