c++ - 虚函数查找的规则是什么?

标签 c++ overriding virtual-functions

#include <iostream>
class base
{
    public:
    virtual void print (int a)
    {   
        std::cout << "a: " << a << " base\n";
    }   
    virtual void print (int a, int b)
    {   
        std::cout << "base\n";
    }   
};

class derived : public base
{
    public:
    virtual void print (double d)
    {   
        std::cout << "derived\n";
    }   
};

int main ()
{
    int i = 10; 
    double d = 10000.0;
    base *b = new derived (); 
    b->print (i, i); 
    b->print (d);

    return 0;
}

这个函数的输出是:

base
a: 10000 base
  • 为什么 b->print (d) 不调用派生类实现并且 在 'd' 上执行静态转换以提供与基类的匹配 实现 ?
  • 在虚函数查找期间这里应用什么规则?

最佳答案

derived::print 不会覆盖 base 中的任何成员函数。它被声明为具有类型为 double 的单个参数,但是 base 中名为 print 的两个虚成员函数被声明为具有一个和两个参数int 类型。

当您使用 b->print(d) 时,在重载决策期间仅考虑 base 中的成员函数,因此只有 void base::print( int)void base::print(int, int) 被考虑在内。 void derived::print(double) 无法找到,因为编译器不知道 b 指向 derived 对象。

如果 derived 要覆盖在 base 中声明为虚拟成员函数的两个 print 函数之一,那么该覆盖将在运行时。

(在某种程度上相关的说明中,derived::print 隐藏了两个 base::print 成员函数,因此如果您尝试使用其中一个基类 print 函数,例如 derived().print(1, 1),它将失败。您需要使用 using 声明使这些成员函数在名称查找。)

关于c++ - 虚函数查找的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5372656/

相关文章:

Java - 具有泛型类型参数的重写方法,并在调用它时对其进行类型转换

c++ - CRTP 能否完全替代较小设计的虚拟功能?

c++ - std::filesystem::directory_iterator 真的是迭代器吗?

c++ - 迷失在指针的世界里

android - 为什么@override 不起作用?

C++ 调试 "smell"

c++ - 如何定义以派生类型作为参数的虚函数?

c++ - 如何在QT中写一个旋转里程表?

c++ - C++ 中有没有办法让循环的输出显示在同一行上?

c++ - C++ 构造函数重载的经验法则?