我遇到的情况是我正在使用公共API,并且需要“覆盖”父类中的函数,但是该函数尚未声明为虚拟。尽管它很笨拙,但是我已经决定使用下面提到的代码来更改父类函数的可见性:这是c ++中隐藏特定函数的一种方式。
但是,我遇到了一个问题,即父类对该函数的重载具有非常相似的参数,因此,即使我已使父类的函数成为作用域,但仍会收到错误消息“歧义调用重载函数”在我的孩子课堂上不公开。我简化了以下解决方案以说明问题:
class Parent
{
public:
void doSomething(void* pointer) {}
};
class Child : public Parent
{
public:
void doSomething(const char* pointer) {}
private:
using Parent::doSomething;
};
int main()
{
Child childInstance;
childInstance.doSomething(nullptr); // error: 'Parent::doSomething': ambiguous call to overloaded function
}
这是一个错误吗?如果没有,我该如何解决?当我显式声明doSomething()
为private时,为什么编译器甚至在父类的名称空间中进行搜索,我感到困惑。
我正在使用MSVC 2019。
我不想执行以下任一操作:
这是一个错误吗?我对为什么编译器甚至在父类的名称空间中进行搜索感到困惑
编译器不必查看父类。您明确地告诉他您要使用Parent::doSomething;
。
此外,重载解析发生在私有/公共访问之前(参见cppreference):
成员访问不会影响可见性:私有和私有继承成员的名称是可见的,并通过重载解析加以考虑,仍会考虑对不可访问的基类的隐式转换,等等。成员访问检查是解释任何给定语言构造之后的最后一步。该规则的目的是,用公共场所替换任何私人场所绝不会改变程序的行为。
两种重载都是同等好的匹配,因此模棱两可。传递avoid*
应该可以选择所需的重载:
childInstance.doSomething(static_cast<void*>(nullptr));
要使方法从Parent
as中隐藏private
并解决歧义,可以添加一个间接级别:
class Parent
{
public:
void doSomething(void* pointer) {}
};
class Intermediate : public Parent {
using Parent::doSomething;
};
class Child : public Intermediate
{
public:
void doSomething(const char* pointer) {}
};
int main()
{
Child childInstance;
void* p;
//childInstance.doSomething(p); // error
childInstance.doSomething(nullptr); // fine
}
该intermediate
保证Parent::doSoemthing
是私人和通话不再是模糊的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句