我可以只覆盖继承中的一个方法吗?

时间:2013-03-16 15:25:31

标签: c++ inheritance function-overriding

我的C++代码如下:

#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;
}

在编译期间我得到:

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

当我尝试在B的f(int)之后使用覆盖时,我得到了同样的错误。

C ++中是否可以只覆盖1个方法?我一直在寻找使用override的代码示例,它将在我的机器上编译但尚未找到。

5 个答案:

答案 0 :(得分:10)

问题是,班级f() 中的虚拟函数B隐藏了 A的非虚拟重载,名称相同。您可以使用using声明将其纳入范围:

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

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

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:4)

你被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)的范围(BA::f(int)中可以看到两个 B::f(int)个函数。 C ++也有一些规则来涵盖这一点,所以如果你在b.f(3);中添加(例如)mainusing A::f;到位)你仍然不会有歧义 - 它如你所料,打电话给b::f(int)

答案 3 :(得分:1)

派生类中定义的函数f通过名称f隐藏基类函数。
要将隐藏函数放在派生类的范围内,您需要添加:

using A::f;

到您的基类定义。

好读:

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

答案 4 :(得分:0)

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