6

My C++ code is as follows:

#include<iostream>
using namespace std;

class A
{
    public:
        virtual void f(int i)
        {
            cout << "A's f(int)!" << endl;
        }
        void f(int i, int j)
        {
            cout << "A's f(int, int)!" << endl;
        }
};

class B : public A
{
    public:
        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};

int main()
{
    B b;
    b.f(1,2);
    return 0;
}

during compilation I get:

g++ -std=c++11 file.cpp 
file.cpp: In function ‘int main()’:
file.cpp:29:9: error: no matching function for call to ‘B::f(int, int)’
file.cpp:29:9: note: candidate is:
file.cpp:20:16: note: virtual void B::f(int)
file.cpp:20:16: note:   candidate expects 1 argument, 2 provided

When I tried to use override after B's f(int), I got the same error.

Is it possible in C++ to override only 1 method? I've been searching for a code example using override that will compile on my machine and haven't found one yet.

4

5 回答 5

11

The problem is that your virtual function f() in class B hides A's non-virtual overload with an identical name. You can use a using declaration to bring it into scope:

class B : public A
{
    public:
        using A::f;
    //  ^^^^^^^^^^^

        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};
于 2013-03-16T15:28:23.353 回答
6

您将名称“f”覆盖为方法名称。因此,任何重载也将被覆盖。

您可以使用using关键字,只是告诉编译器也查看基类:

class B : public A
{
    public:
        using A::f;
        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};
于 2013-03-16T15:30:19.077 回答
5

您被 C++ 中名称查找的工作方式所困扰。编译器搜索连续的范围,直到找到一个范围内至少有一个名称匹配的项目。

假设 item 是一个函数,然后它会在它在该范围内找到的具有该名称的函数之间进行重载解析。如果这些都不起作用,它就不会继续搜索更多范围以找到更合适的范围。

但是,在这种情况下,您可以让它搜索父类:

class B : public A
{
    public:
        using A::f;
        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};

乍一看,该using声明可能会产生歧义。例如,using A::f;现在有两个 函数在的范围内f(int)可见(和)。C++ 也有一些规则来涵盖这一点,所以如果你添加(例如)在(就地)你仍然不会有歧义——它会像你期望的那样调用。BA::f(int)B::f(int)b.f(3);mainusing A::f;b::f(int)

于 2013-03-16T15:32:05.547 回答
1

The function f defined in derived class hides the base class functions by the name f.
To bring the hidden function in scope of derived class you need to add:

using A::f;

to your base class definition.

Good Read:

What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?

于 2013-03-16T15:27:41.853 回答
0

是的,可以只覆盖一个类的一个方法,使其成为虚拟方法。在继承类中声明时,非 virtual 将被遮蔽。

于 2013-03-16T15:29:18.710 回答