C++二级继承后访问基类类型为何需要使用完全限定名?
问题原因
这个错误是C++的**注入类名(Injected Class Name)**规则和默认私有继承共同作用的结果,和编译器隐式占用标识符无关:
- C++标准规定,每个类都会将自身的类名隐式注入到自身的作用域中,这个注入的名字在类作用域内的优先级高于全局作用域的同名标识符。
- 你定义
B类时使用的是class B : A的写法,class类型的默认继承权限为私有继承。这意味着A的所有成员(包括它的注入类名A)都会被B以私有权限继承。 - 当你在
C类的作用域内写A时,名字查找的顺序会优先查找父类B的作用域,此时会匹配到B私有继承来的注入类名A,但C作为B的派生类没有权限访问B的私有成员,因此抛出访问不可达的错误。你看到的错误提示里的A::A就是指向这个注入类名。
重写有效性判断
你当前的写法可以正常完成虚函数重写:B类的do_something方法参数里的A&,在B的作用域内查找时,匹配到的就是全局作用域的::A类型,和C类方法里显式写的::A&是完全相同的类型,函数签名一致,满足虚函数重写的要求。
常见优化建议
B类方法中的A不需要额外加全局限定符:在B自身的作用域内,可以正常访问私有继承来的注入类名A,解析结果和::A完全一致。- 如果你不需要私有继承的特性,建议显式指定公有继承:将
class B : A改为class B : public A,此时A的注入类名会被B以公有权限继承,C类中可以直接使用A,不需要加全局限定符。 - 如果确实需要保留私有继承,也可以在
B类的public区域添加using A;声明,将注入类名A的权限开放给派生类,同样可以避免C类里的限定符问题。 - 定义类继承时尽量显式指定继承权限,不要依赖默认的私有继承规则,减少隐式问题的出现。
内容的提问来源于stack exchange,提问作者Marty Cagas
相关产品推荐
相关产品推荐

