多重继承下函数调用歧义:访问控制是否影响名称解析?
C++名称解析与重载决议的访问权限问题
先看这段引发问题的代码:
#include <iostream> using namespace std; class base1 { public: void printing() { cout << "Using base1" << endl; } }; // base2 包含私有版本的 printing 函数 class base2 { void printing() { cout << "Using base2" << endl; } }; class derived :public base1, base2 { }; int main() { derived* d = new derived(); d->printing(); }
这段代码被IDE提示调用存在歧义,核心原因是C++在名称解析阶段完全不考虑函数的访问说明符。
结合重载决议的步骤:
构建候选函数集。
将集合筛选为仅包含可行函数。
分析集合以确定最佳可行函数(可能涉及隐式转换序列的排序)。
这里的「可行函数」筛选仅做类型匹配检查,完全不关心函数的访问权限(public/protected/private),也不考虑函数是否被=delete修饰。
具体到这段代码的执行逻辑:
- 名称解析阶段:编译器在
derived类作用域中找不到printing,就会去两个基类中查找,最终把base1::printing和base2::printing都加入候选函数集,不会因为base2::printing是私有就排除它。 - 可行函数筛选:两个函数都是无参函数,和调用的参数列表完全匹配,因此都被保留为可行函数。
- 最佳函数选择:两个函数来自不同基类,没有优先级差异,编译器无法确定要调用哪一个,因此直接报歧义错误。
需要注意的是,访问权限检查是在重载决议完成之后才进行的——如果代码中只有一个printing函数,哪怕它是私有成员,编译器也会先完成重载决议,再报「无法访问私有成员」的错误,而不是提前用访问权限过滤候选函数。
内容的提问来源于stack exchange,提问作者Yiqun Cui
相关产品推荐
相关产品推荐

