#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'
上执行静态强制转换以提供与基类的匹配
实施?答案 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