c – 这与函数重载有什么关系?

前端之家收集整理的这篇文章主要介绍了c – 这与函数重载有什么关系?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
This基本上是第21项中给出的示例的副本.在Herb 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;
}

代码打印Base :: f(double),我没有问题.但我无法理解作者在第122页的顶部给出的解释(重点是我的):

Interestingly,even though the Base* pb is pointing to a Derived
object,this calls Base::f( double ),because overload resolution is
done on the static type (here Base),not the dynamic type (here
Derived)
.

我的理解是,调用pb-> f(1.0)是一个虚拟调用,Base :: f(double)是Derived中f(double)的最终覆盖.这与函数重载有什么关系?

解决方法

这里微妙的部分是虚方法是一种调度函数调用的机制,而重载是一种影响调用解析的特性.

也就是说,对于任何调用,编译器需要确定应该调用哪个方法(解析它);之后,在逻辑上不同的操作中,它需要生成调用方法的正确实现的代码(调度它).

根据上面给出的Base和Derived的定义,我们可以很容易地推断,如果在Base *上调用f(double),那么应该将调用分派给任何派生的覆盖(如果适用)而不是基本实现.但回答这个回答的问题完全不同于

When the source says pb->f(1.0),which of the methods named f
should be used to resolve the method call?

正如Sutter解释的那样,规范说当解析调用时,编译器将查看在pb指向的静态类型上声明的名为f的方法;在这种情况下,静态类型是Base *所以在Derived上声明的重载(不是覆盖!)根本不会被考虑.但是,如果调用解析的方法是虚拟的,那么Derived上提供的可能实现将按预期使用.

原文链接:https://www.f2er.com/c/120082.html

猜你在找的C&C++相关文章