C++自动生成类自定义Hook访问宿主成员变量方案咨询
结论
你提出的「Hook声明为NotMyClass友元+传递宿主this指针」的方案完全可行,是当前约束下成本最低、稳定性最高的实现方式。
具体实现步骤
你既然已经能调整代码生成模板,在NotMyClass中注入Hook类型成员和hook_.DoSomethingCustom()调用点,只需要在生成模板中补两处调整即可,不需要手写任何业务逻辑到自动生成类里:
- 在
NotMyClass的类定义中加友元声明,给Hook开放访问权限,这个操作不会改变类内存布局,也不会影响原有生成逻辑:
class NotMyClass { // 模板里加这一行就行 friend class Hook; public: void DoSomething() { // 把原有无参调用改成传this hook_.DoSomethingCustom(this); } protected: Hook hook_; int not_my_class_inner_variable_1_; Node not_my_class_inner_variable_2_; // 其余自动生成的成员不变 };
- 对应修改
Hook类的方法签名,接收宿主指针,拿到指针后加了友元就可以直接访问所有保护/私有成员:
class Hook { public: void DoSomethingCustom(NotMyClass* owner) { // 直接访问宿主成员即可 int val1 = owner->not_my_class_inner_variable_1_; Node& val2 = owner->not_my_class_inner_variable_2_; // 自定义逻辑 } };
无法修改调用传参时的兼容方案
如果你的生成规则完全不允许调整DoSomethingCustom()的调用参数(即不能显式传this),可以通过成员偏移计算拿宿主指针,不需要修改调用点:
- 首先用编译期校验确认
NotMyClass是标准布局类型,自动生成的无自定义虚函数、无多继承的纯业务类一般都满足要求:static_assert(std::is_standard_layout_v<NotMyClass>, "NotMyClass must be standard layout"); - 在
DoSomethingCustom内通过当前Hook对象的地址反推宿主地址:void DoSomethingCustom() { constexpr size_t hook_member_offset = offsetof(NotMyClass, hook_); NotMyClass* owner = reinterpret_cast<NotMyClass*>( reinterpret_cast<char*>(this) - hook_member_offset ); // 后续访问成员的逻辑和传参方案一致 }
注意:非标准布局类型使用
offsetof是未定义行为,这种场景不要用这个方案,优先调整模板传this。
不推荐的方案说明
- 继承重写方案不符合你的约束,且自动生成类一般不会预留可重写的虚函数接口,本身适配成本极高
- 不通过友元直接强转指针访问保护成员会直接触发编译错误,C++的成员访问权限是编译期强校验的,没有权限哪怕知道内存布局也无法通过编译
- 直接内存拷贝宿主成员的方式性能差,遇到非平凡类型(比如你代码中的
Node、std容器等)会直接触发未定义行为,完全不要用。
内容的提问来源于stack exchange,提问作者danish sodhi
相关产品推荐
相关产品推荐

