You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++通过继承与成员函数指针访问protected成员是否为未定义行为?

结论

你的理解存在偏差,这段代码不属于未定义行为,是C++社区广泛使用的合法protected成员访问技巧,通常被称为Protected Hack。


具体解释

1. &Hacky::foo的本质

你在Hacky类中通过using B::foo的声明,只是将继承自基类链的foo成员函数暴露为Hacky的public成员,并没有在Hacky类中新增独立的foo函数:

  • 这个foo的实际定义类是最上层的A,因此&Hacky::foo得到的成员指针类型是void (A::*)(),指向A类的foo成员,和Hacky类本身没有绑定关系。
  • 你这里的using声明只是修改了该继承成员的访问权限,没有改变成员本身的归属。

2. 成员指针调用的合法性

根据C++标准对内置成员指针访问运算符的要求:当调用E1.*E2时,只要E1的动态类型包含E2指向的成员所属的类(此处为A)作为基类,行为就是明确定义的。
你代码中a的动态类型是B,B是A的公有派生类,天然包含完整的A基类部分,因此(a.*ptr)()的调用完全合法,会正常执行A::foo的逻辑。


常见误区说明

你误以为Hacky::foo是Hacky类的独有成员,因此觉得动态类型为B的对象不包含该成员。这个误解的核心是没有区分成员的访问路径和成员的实际归属类:Hacky::只是你取成员地址时使用的访问路径,不改变成员本身属于A的事实。

内容的提问来源于stack exchange,提问作者Davidbrcz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:18:04