C++私有继承歧义疑问:为何无法重复私有继承同一基类?
我尝试定义Executive类,让它public继承Manager类,同时private继承Money类,但编译器抛出警告:direct base 'Money' inaccessible in 'Executive' due to ambiguity。我的预期是Executive里的Manager::get()调用Money::get()来存储工资,而自身继承的Money::get()用来存额外奖金。我知道私有继承可以当组合的替代方案,也能用来隐藏基类接口实现派生类,但搞不懂为啥会出现歧义——按私有继承的规则,派生类的子类没法用这个继承关系,怎么还会触发问题?虽然我知道用组合就能解决,但还是想弄明白这个歧义到底是怎么来的。
代码示例:
class Money { public: void get() {std::cin >> amount;} private: float amount; }; class Employee { public: void get() {std::cin >> lastName;} private: std::string lastName; }; class Manager : public Employee, private Money // money用来存储工资 { public: void get() {Employee::get(); Money::get();} }; class Executive : public Manager, private Money // money用来存储额外奖金 // 警告:direct base 'Money' inaccessible in 'Executive' due to ambiguity { public: void get() {Manager::get(); Money::get();} };
重复继承导致多个基类实例
Executive一方面通过Manager间接私有继承了Money,另一方面又直接私有继承了Money,这会让Executive内部存在两个完全独立的Money子对象。私有继承确实会让Executive的子类或外部代码无法访问这些Money的接口,但Executive自己内部是能看到这两个实例的。名称查找时的歧义冲突
当你在Executive::get()里写Money::get()时,编译器根本搞不清楚你要调用的是哪一个Money的get()——是从Manager那边传下来的那个,还是Executive自己直接继承的那个。哪怕私有继承限制了外部访问,在Executive内部,这两个Money的成员名称完全重合,直接触发了歧义警告。访问控制和名称查找是独立机制
C++里的访问控制(public/private)和名称查找是分开的两个步骤:编译器先做名称查找,找到所有匹配的名称后,才会检查你有没有权限访问。这里两个Money的get()都能被找到,但来源不明确,直接就报歧义了,连访问检查的步骤都没走到。
说白了,问题的核心不是私有继承的可见性,而是同一个基类被多次继承,产生了多个独立的子对象,导致名称查找时无法确定目标。
内容的提问来源于stack exchange,提问作者Sju Ton

