c++ - 具有不同签名的两个函数的继承隐藏了非虚函数

标签 c++ inheritance

请原谅这个晦涩的标题。这可能是重复的,但我找不到正确的短语。

考虑以下继承层次结构。

class A
{
public:
    virtual void Foo(int i) { printf("A::Foo(int i)\n"); }
    void Foo(int a, int b) { Foo(a + b); }
};

class B : public A
{
public:
    void Foo(int i) override { printf("B::Foo(int i)\n"); }
};

class C : public B
{
public:
    void Bar() { Foo(1, 2); } //error C2660: function does not take two arguments
};

A 有两个名为 Foo 的方法,它们具有不同数量的参数。其中只有一个是虚拟的。
B 覆盖虚拟方法。
C 尝试调用非虚方法并遇到错误。

将该方法调用为 A::Foo(1, 2) 确实可以正常工作。

问题: 为什么编译器不能推断出在 A 上找到了正确的方法?

这似乎很奇怪,我们必须在调用中显式添加 A:: ,例如:

C c;
c.A::Foo(1, 2);

最佳答案

因为在B的类作用域中找到了名为Foo的成员函数,然后名称查找停止,所以类中的Foo A 不可见,即使 A 类中的版本更合适,也不会考虑进行重载决策。这是名称隐藏。

您可以使用 using 将它们引入相同的作用域,并使重载解析按您的预期工作。如:

class C : public B
{
    using A::Foo;
    using B::Foo;
public:
    void Bar() { Foo(1, 2); }
};

参见Unqualified name lookup

LIVE

关于c++ - 具有不同签名的两个函数的继承隐藏了非虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35597442/

相关文章:

c++ - 如何静态检查两个比率是否相等?

java - 返回类型不兼容

c++ - 这是非多态继承的一个很好的理由吗?

javascript - 如何构建可与不同的底层同步方法一起重复使用的嵌套 backbone.js 模型

c++ - 遍历数组最有效的方法是什么? (c++)

c++ - Lua 和伪造的 Typecast

c++ - 使用 constexpr 和 lambda 时出现编译器错误

c++ - Qt - 如何解决 QScroller 最大尺寸限制(16777215 像素)

jquery - 从前置的 div 中删除 .img css

xaml - 如何从Silverlight中的XAML中定义的用户控件正确继承