加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 04:54:56 所属栏目:百科 来源:网络整理
导读:This基本上是第21项中给出的示例的副本.在Herb Sutter的书Exceptional C中覆盖虚函数. #include iostream#include complexusing namespace std;class Base{public: virtual void f(int); virtual void f(double); virtual ~Base() {};};void Base::f(int) {
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上提供的可能实现将按预期使用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读