我试图了解虚拟函数的工作原理,但我只能停留在某个部分。

我写了这个小程序:

class First
{
public:
    virtual void f(int a)
    {
        cout << "First!" << endl;
        cout << a << endl;
    }
};

class Second : public First
{
public:
    void f(int a) {
        cout << "Second!" << endl;
        cout << a << endl;
    }
};

void main() {
    Second s;
    First *p = &s;
    p->f(5);
    First n;
    p = &n;
    p->f(3);
    _getch();
}

此代码导致:
Second!
5
First!
3

However, if I change int in the Second::f() function to a different type, like this:

class First
{
public:
    virtual void f(int a) {
        cout << "First!" << endl;
        cout << a << endl;
    }
};

class Second : public First
{
public:
    void f(double a) { //double instead int here!
        cout << "Second!" << endl;
        cout << a << endl;
    }
};

void main() {
    Second s;
    First *p = &s;
    p->f(5);
    First n;
    p = &n;
    p->f(3);
    _getch();
}

我的程序从不调用Second::f(),结果是这样:

第一的!
5
第一的!
3

有人可以向我解释为什么会这样吗?

最佳答案

使用虚拟函数分派(dispatch)时,将调用所谓的“最终替代程序”。为了使一个函数甚至覆盖继承的虚函数,它必须满足一些条件:



-ISO/IEC 14882:2001(E)§10.3(加粗强调)

很简单,在第二个示例中,Second::f(double)的参数列表与First::f(int)的参数列表不同,因此Second::f(double)不是(自动)虚拟的,并且不会覆盖First::f(int)

C++ 11关键字override声明了您的意图,即方法将覆盖继承的虚拟方法,以便编译器可以告诉您何时不这样做。例如,您是否这样做了:

void f(double a) override {

编译器会为您提供此诊断信息,以通知您它实际上并未覆盖任何内容,甚至会通知您原因(“第一个参数的类型不匹配('int'与'double')”):
main.cpp:15:18: error: non-virtual member function marked 'override' hides virtual member function
void f(double a) override { //double instead int here!
                 ^
main.cpp:7:14: note: hidden overloaded virtual function 'First::f' declared here: type mismatch at 1st parameter ('int' vs 'double')
virtual void f(int a) {
             ^

关于c++ - 具有不同参数类型的虚函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43644194/

10-11 22:35
查看更多