当前位置: 首页 > article >正文

C++——一道关于多态的经典面试题

        这个试题的问题是以下程序输出结果是什么?

        A: A->0 B: B->1 C: A->1 D: B->0 E: 编译出错 F: 以上都不正确  

    class A
    {
    public:
        virtual void func(int val = 1){ std::cout<<"A->"<< val <<std::endl;}
        virtual void test(){ func();}
    };

    class B : public A
    {
    public:
        void func(int val = 0){ std::cout<<"B->"<< val <<std::endl; }
    };

    int main(int argc ,char* argv[])
    {
        B*p = new B;
        p->test();
        return 0;
    }

        首先这道题的第一个坑在于,可能有的人看一遍代码,可能会觉得p是B类型的一个指针,指向的也是一个B类型的对象,可是B类中并没有test函数,所以答案是E。但是B类继承了A类,虽然在A类中test函数是一个虚函数,并且在B类中并没有被重写,但是test函数同样通过虚函数表的形式继承给了B类,所以E选项是错误的。

        这道题的第二个坑在与B类中的func函数没有加virtual修饰,因此会有些人认为这个func函数就不是一个虚函数,因此在p调用test函数时,test函数所调用的func函数就是A类中的func函数,所以输出为A->1,因此选C。但是虽然B类中的func函数并没有被virtual修饰,但是在虚函数的定义中我们可以知道,派生类中的虚函数可以不用virtual修饰,虽然这是一种不规范的写法,但是派生类在从基类继承这个函数的时候,就已经把这个函数的虚函数性质一并继承下来了,也就是说虽然这B类中的func函数并没有用virtual修饰,但是A类中的func函数已经被virtual修饰了,所以B类中的func函数也具有虚函数的性质。所以C选项也是错误的。

        这道题的第三个坑就在第二坑分析正确的基础上,经过第二点的分析,我们知道了B类的func函数也是一个虚函数,并且B类重写了A类的func函数,所以在B类的虚函数表中B类自己的func函数的地址已经对继承下来的虚函数表里原来的func函数地址进行了覆盖,因此在调用func函数的时候,调用的是自己的实现的func函数,因此输出的结果是B->0,选D。但是这样就掉到这道题的最后一个坑里面了,因为虚函数完成重写以后,在调用时,相当于是把派生类的虚函数重写以后的函数体覆盖到基类的虚函数上,当基类的虚函数的参数列表有缺省值时,并不会对参数列表进行修改,因此这里test函数调用的func函数的本质是

virtual void func(int val = 1)
{     
    std::cout<<"B->"<< val <<std::endl; 
}

输出的结果是B->1,答案选B。

        所以从这道题里我们可以得出一个结论:如果虚函数的参数列表中设置有缺省值,那么我们的派生类在重写这个虚函数时不要对这个缺省值进行修改,因为修改以后在调用时并不会把修改后的缺省值应用到参数上。


http://www.kler.cn/news/303241.html

相关文章:

  • 宠物空气净化器应该怎么选择才能选到除毛效果好的产品
  • mysql-搭建主从复制
  • pdf怎么压缩?分享5种压缩PDF文件的方法
  • 《CSS新世界》书评
  • 使用程序集解析的方式内嵌dll到exe中
  • #名词区别篇:npx pnpm npm yarn区别
  • gitlab无法push(pre-receive hook declined)
  • 如何使用 Choreographer 进行帧率优化
  • 旅游网站开发:SpringBoot框架实战
  • 观察者模式与hook机制的联系
  • Java面试篇基础部分-Java序列化
  • 高性能缓存利器:Caffeine 在 Spring Boot 中的应用
  • 快速完成论文初稿写作的ChatGPT提示词分享
  • 怎样将vue项目 部署在ngixn的子目录下
  • linux环境下手动安装mysql
  • holynix靶机详解
  • PROTOTYPICAL II - The Practice of FPGA Prototyping for SoC Design
  • 【ShuQiHere】快速排序(Quick Sort):揭开高效排序算法的神秘面纱
  • 观察者模式observer
  • pdf 转 jpg
  • 黑马点评15——分布式缓存-Redis分片集群
  • C文件操作
  • Sentinel 使用案例详细教程
  • K8S - Volume - NFS 卷的简介和使用
  • SpringBoot - 入门
  • 【WPF】Popup的使用
  • IO中断原理浅析
  • 分销系统架构文档
  • OpenGL(三)着色器语言GLSL
  • 深度学习速通系列:依存分析