C++非虚菱形继承下访问上层类成员的规范语法
嘿,我来帮你把这个多继承的访问问题理得明明白白~
多继承下歧义成员的访问规范
你的类结构里,lower其实包含了三个完全独立的upper子对象:分别是通过left继承来的、通过right继承来的,以及lower自己直接继承的。因为没用到虚继承,这三个子对象各自拥有独立的base成员,所以访问时必须明确指定路径,否则编译器会报歧义错误。
1. 访问left/right路径的upper成员
规范的写法是使用**作用域解析符::**明确指定继承链条:
- 访问
left路径的base:lower_obj.left::upper::base - 访问
right路径的base:lower_obj.right::upper::base
如果left/right类本身没有和base同名的成员,也可以简化成lower_obj.left::base或lower_obj.right::base——编译器会自动回溯到upper类的成员。不过更严谨的写法是加上upper::,尤其是当子类有同名成员时,能精准区分要访问的是父类upper的成员。
2. 访问lower直接继承的upper成员
要直接访问lower自己继承的那个upper子对象的成员,同样用作用域解析符,直接指定upper::即可:
lower obj; obj.upper::base = 5; // 直接访问lower直接继承的upper的base
完整可运行示例
#include <iostream> class upper { public: int base;}; class left : public upper {}; class right : public upper {}; class lower : public right, public left, public upper {}; int main(){ lower obj; // 两种写法访问left路径的upper成员 obj.left::upper::base = 1; obj.left::base = 2; // 简化写法,结果覆盖上面的1 // 两种写法访问right路径的upper成员 obj.right::upper::base = 3; obj.right::base = 4; // 简化写法,结果覆盖上面的3 // 访问lower直接继承的upper成员 obj.upper::base = 5; // 验证不同子对象的成员是独立的 std::cout << "left路径的base值: " << obj.left::base << std::endl; std::cout << "right路径的base值: " << obj.right::base << std::endl; std::cout << "lower直接继承的base值: " << obj.upper::base << std::endl; return 0; }
关键提醒
这些写法都是C++标准认可的规范用法,不存在“不规范”的问题。要不要加upper::取决于子类是否有同名成员:如果子类没有同名成员,简化写法足够用;如果有同名成员,必须加上upper::才能明确访问父类的成员。另外,因为没有虚继承,这三个upper子对象完全独立,修改其中一个不会影响另外两个的数值。
内容的提问来源于stack exchange,提问作者Timofeus
相关产品推荐
相关产品推荐

