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
相关产品推荐
相关产品推荐

