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

时间:2011-03-21 00:29:19

标签: c++ override 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'上执行静态强制转换以提供与基类的匹配 实施?
  • 在虚函数查找期间应用了什么规则?

3 个答案:

答案 0 :(得分:8)

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

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

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

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

答案 1 :(得分:1)

重载解析在编译时发生。覆盖发生在运行时。

因此,首先发生b->print(d);的重载决策。这会选择Base::print(int),因为它是唯一的一个参数print

在运行时,b指向Derived没有覆盖Base::print(int)的对象。因此,仍然会调用Base::print(int)

答案 2 :(得分:0)

因为double可以在它看到的第一个定义中自动转换为int(在基类中)

请参阅explicit关键字或this question