【问题标题】:Calling overrided virtual function instead of overloaded调用重写的虚函数而不是重载
【发布时间】:2016-10-31 23:33:43
【问题描述】:

假设我有这部分代码:

#include<iostream>
using namespace std;
class A {
public:
    virtual int f(const A& other) const { return 1; }
};
class B : public A {
public:
    int f(const A& other) const { return 2; }
    virtual int f(const B& other) const { return 3; }
};

void go(const A& a, const A& a1, const B& b) {
    cout << a1.f(a) << endl; //Prints 2
    cout << a1.f(a1) << endl; //Prints 2
    cout << a1.f(b) << endl; //Prints 2
}
int main() {
    go(A(), B(), B());
    system("pause");
    return 0;
}

我能理解为什么前两个会打印2。但我不明白为什么最后一个打印也是2。为什么它不喜欢B中的重载函数?

我已经看过 thisthis 但我无法从中理解。

【问题讨论】:

  • 因为您使用A 引用来调用f。而A 不知道f(const B&amp; other)

标签: c++ overriding overloading


【解决方案1】:

int B::f(const B&amp; other) const 没有 override int A::f(const A&amp; other) const 因为参数类型不一样。然后它不会通过在基类A 的引用上调用f() 来调用。

如果某个成员函数 vf 在 Base 类和一些 Derived 类,它是直接派生的,或者 间接地,从 Base,有一个成员函数声明 一样的

name
parameter type list (but not the return type)
cv-qualifiers
ref-qualifiers 

那么 Derived 类中的这个函数也是虚的(无论是 不是在其声明中使用关键字 virtual)和 覆盖 Base::vf(无论是否在其 声明)。

如果你使用override specifier(C++11 起)编译器会产生错误。

class B : public A {
public:
    int f(const A& other) const { return 2; }
    virtual int f(const B& other) const override { return 3; }
};

Clang

source_file.cpp:10:17: error: 'f' marked 'override' but does not override any member functions
    virtual int f(const B& other) const override { return 3; }
                ^

如果你在基类中为它添加一个重载,你可能会得到你想要的。请注意,将需要 B 类的前向声明。

class B;
class A {
public:
    virtual int f(const A& other) const { return 1; }
    virtual int f(const B& other) const { return 1; }
};

LIVE

【讨论】:

  • 有道理,结合@ArmenTsirunyan vtable 解释我现在完全理解了。谢谢!
【解决方案2】:

这很容易,真的。您正在对静态类型为A 的对象调用fA 只有一个f,因此vtable 中只有一个条目用于该函数。重载解决发生在编译时。只有在 static 类型为 B

的对象上调用重载才能解决

【讨论】:

    【解决方案3】:

    困惑在于您的:

    int f(const A&amp; other) const { return 2; }

    line 实际上也是虚拟的,并且覆盖了您的 line:

    virtual int f(const A&amp; other) const { return 1; }

    同时,一行:

    virtual int f(const B&amp; other) const { return 3; }

    最终被完全忽略,因为所有内容都与“return 1”行匹配,然后多态地沿着链向上到达“return 2”行。正如另一张海报所说,const B 部分意味着它与多态方法调用不匹配。

    顺便说一句:如果您在第一行得到 2,我怀疑不受欢迎的堆栈行为。我希望是 1。也许尝试像这样分配:

    A a1;
    B b1, b2;
    
    go(a1, b1, b2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 2011-07-16
      • 2017-08-06
      相关资源
      最近更新 更多