C++ 虚拟函数查找的规则是什么? 为什么b->print(d)不调用派生类实现和 对'd'执行静态强制转换,以提供与基类的匹配 实施 在虚拟函数查找期间,此处应用了什么规则
C++ 虚拟函数查找的规则是什么? 为什么b->print(d)不调用派生类实现和 对'd'执行静态强制转换,以提供与基类的匹配 实施 在虚拟函数查找期间,此处应用了什么规则,c++,overriding,virtual-functions,C++,Overriding,Virtual Functions,派生::打印不会覆盖基中的任何成员函数。它被声明为具有类型为double的单个参数,但base中名为print的两个虚拟成员函数被声明为具有类型为int的一个和两个参数 当您使用b->print(d)时,重载解析期间只考虑base中的成员函数,因此只考虑void base::print(int)和void base::print(int,int)无效派生::打印(双精度),因为编译器不知道b指向派生的对象 如果derived要覆盖print中声明为base中的虚拟成员函数的两个函数之一,则会在运
派生::打印
不会覆盖基
中的任何成员函数。它被声明为具有类型为double
的单个参数,但base
中名为print
的两个虚拟成员函数被声明为具有类型为int
的一个和两个参数
当您使用b->print(d)
时,重载解析期间只考虑base
中的成员函数,因此只考虑void base::print(int)
和void base::print(int,int)
<无法找到代码>无效派生::打印(双精度),因为编译器不知道b
指向派生的
对象
如果derived
要覆盖print
中声明为base
中的虚拟成员函数的两个函数之一,则会在运行时调用该覆盖
(在某种程度上相关的注释中,derived::print
隐藏了两个base::print
成员函数,因此如果您试图使用其中一个基类print
函数,例如,derived().print(1,1)
,它将失败。您需要使用using声明使这些成员函数在名称查找期间可用。)因为double可以在它看到的第一个定义(在基类中)中自动转换为int
请参阅explicit
关键字或重载解析在编译时发生。重写发生在运行时
因此,b->print(d)的过载分辨率代码>首先发生。这将选择Base::print(int)
,因为它是唯一的一个参数print
在运行时,b
指向一个派生的
对象,该对象对Base::print(int)
没有覆盖。因此,Base::print(int)
仍然被调用。您使用的是类型Base,而不是派生的。它没有一个需要双精度的函数,所以它将转换为int以找到最佳匹配。
#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