Wak*_*zil 7 c++ overriding overloading c++11
这基本上是Item 21. Overriding Virtual FunctionsHerb Sutter的书中给出的例子的副本Exceptional C++.
#include <iostream>
#include <complex>
using namespace std;
class Base
{
public:
virtual void f(int);
virtual void f(double);
virtual ~Base() {};
};
void Base::f(int) { cout << "Base::f(int)" << endl; }
void Base::f( double ) { cout << "Base::f(double)" << endl; }
class Derived: public Base {
public:
void f(complex<double>);
};
void Derived::f(complex<double>) { cout << "Derived::f(complex)" << endl; }
int main()
{
Base* pb = new Derived;
pb->f(1.0);
delete pb;
}
Run Code Online (Sandbox Code Playgroud)
代码打印Base::f(double),我没有问题.但我无法理解作者在第122页的顶部给出的解释(重点是我的):
有趣的是,即使Base*pb指向Derived对象,它也会调用Base :: f(double),因为重载解析是在静态类型(此处为Base)上完成的,而不是动态类型(此处为Derived).
我的理解是,该呼叫pb->f(1.0)是虚拟呼叫,Base::f(double)是最终置换器f(double)在Derived.这与函数重载有什么关系?
Jon*_*Jon 12
这里微妙的部分是虚方法是一种调度函数调用的机制,而重载是一种影响调用解析的特性.
也就是说,对于任何调用,编译器需要确定应该调用哪个方法(解析它); 之后,在逻辑上不同的操作中,它需要生成调用该方法的正确实现的代码(调度它).
从定义Base和Derived上面给出我们可以很容易的理由是如果f(double)上调用Base*,则调用应(如适用)优先于基实现分派到任何派生覆盖.但回答这个回答的问题完全不同于
当源说
pb->f(1.0),f应该使用哪个方法来解析方法调用?
正如Sutter解释的那样,规范说当解析调用时,编译器将查看在f指向的静态类型上声明的方法pb; 在这种情况下,静态类型是Base*如此重载(不是覆盖!)声明Derived将不会被考虑.但是,如果调用解析的方法是virtual,Derived则将按预期使用提供的可能实现.