C++面试题-面向对象-多态性与虚函数

问:在C++程序中调用被C编译器编译后的函数,为什么要加extern "C"?

答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:void foo(int c,int y); 该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern "C"来解决名字匹配问题。(其实这就是表明此函数是C语言编写的)

问:多态是什么?作用是什么?

答:是对于不同对象接收相同消息时产生不同的动作。C++的多态性具体体现在运行和编译两个方面:

  1. 在程序运行时的多态性通过继承和虚函数来体现;
  2. 在程序编译时多态性体现在函数和运算符的重载上;
  3. 编译时多态性:通过重载函数实现,函数模板;
  4. 运行时多态性:通过虚函数实现。

作用:

  1. 隐藏实现细节,使得代码能够模块化;扩展代码模块。实现代码重用。
  2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。说白了,就是(纯)虚函数。

问:多态的两个必要条件?

答:

  1. 父类需要定义虚函数,子类改写该函数。
  2. 定义一个基类指针,调用子类构造函数构建对象。

简答版:

  1. 一个基类的指针或引用指向一个派生类对象。
  2. 虚函数。

问:什么叫静态关联,什么叫动态关联?

答:

  1. 在多态中,如果程序在编译阶段就能确定实际执行动作,则称为静态关联,即编译时多态性。
  2. 如果等到程序运行才能确定叫动态关联,即运行时多态性。

问:以下关于多态性的描述中,错误的是()

A. 动态多态是通过类的继承关系和虚函数来实现的。

B. 静态多态是通过函数的重载或运算符的重载来实现的。

C. 多态性通常使用虚函数或重载技术来实现

D. 为实现动态多态,基类必须定义为含有纯虚函数的抽象类。

答:D

分析:动态多态,基类可以都有虚函数和纯虚函数,也可以两者中存在一种,但不可以两者都没有。

问:类成员函数的重载、覆盖和隐藏的区别?

答:成员函数被重载的特征:

  1. 相同的范围(在同一个类中);
  2. 函数名字相同;
  3. 参数不同;
  4. virtual关键字可有可无。

覆盖是指派生类函数覆盖基类函数,特征是:

  1. 不同的范围(分别位于派生类与基类);
  2. 函数名字相同
  3. 参数不同;
  4. 基类函数必须有virtual关键字。

“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

  1. 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数被隐藏(注意别与重载混淆)。
  2. 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏。(注意别与覆盖混淆)

简答版:

  1. 重载:在同一个类中,存在两个以上的同名但参数不同的函数。
  2. 覆盖:基类指向派生类,两者的函数同名但参数不同的(纯)虚函数。
  3. 隐藏:派生类的函数与基类的函数同名,参数可能相同也可能不同,但是基类没有virtual关键字。

问:虚函数是什么?作用是什么?

答:虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态覆盖(Override)。为了允许用基类的指针来调用子类的这个函数。当基类的指针指向子类对象时候,该定义在基类的虚函数已经成为子类的函数,是属于子类的。其他成员函数是属于父类的。

虚函数,它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。

问:纯虚函数是什么?作用是什么?

答:纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”:

virtual void funtion()=0

引入原因:

  1. 为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
  2. 在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。

为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。

声明了纯虚函数的类是一个抽象类。所以,用户不能创建类的实例,只能创建它的派生类的实例。

纯虚函数最显著的特征是:它们必须在继承类中重新声明函数(不要后面的=0,否则该派生类也不能实例化),而且它们在抽象类中往往没有定义。

定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。

纯虚函数的意义,让所有的类对象(主要是派生类对象)都可以执行纯虚函数的动作,但类无法为纯虚函数提供一个合理的缺省实现。所以类纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它”。

注意:所有在基类的纯虚函数都要在子类当中被实现,否则子类仍然是个抽象类。

问:虚函数表是什么?作用是什么?

答:虚函数表是一块连续的内存,每个内存单元中记录一个JMP指令的地址。

  1. 虚函数是通过一张虚函数表来实现的。
  2. 每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有类对象共享。
  3. 类的每个虚成员占据虚函数表中的一行。
  4. 如果类中有N个虚函数,那么其虚函数表将有N*4字节的大小。在有虚函数的实例中分配了指向这个表的指针的内存。

解决问题:解决了继承、覆盖的问题。

问:虚函数与普通成员函数的区别?

答:虚函数有virtual关键字,有虚指针和虚函数表。虚指针就是虚函数的接口,而普通成员函数没有。

问:内联函数和构造函数能否为虚函数?

答:两者都不能为虚函数。

问:什么是函数的早绑定和晚绑定?

答:多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定(也属于动态绑定)。所以早绑定是非多态的函数地址绑定,该函数地址在编译期间是固定的。而固定的地址将始终调用到同一个函数,这就无法实现一个接口。虚函数就是个晚绑定,而普通函数是早绑定。

问:构造函数和析构函数的调用顺序?析构函数为什么要虚拟(设置为虚函数)?

答:构造函数的调用顺序:基类构造函数--对象成员构造函数--派生类构造函数;

析构函数的调用顺序与构造函数相反。

析构函数虚拟式为了防止析构不彻底,造成内存的泄露。

问:什么时候需要虚析构函数?

答:当基类指针指向用new运算符生成的派生对象时,delete基类指针时,派生类部分没有释放掉而造成释放不彻底对象,需要虚析构函数。

问:什么函数不能声明为虚函数?

答:构造函数。

问:怎样消除多重继承中的二义性?

答:

  1. 成员限定符
  2. 虚基类

问:什么是上转型对像,主要作用是什么?

答:假设A类是B类的父类,当用子类创建一个对象,并把这个对象的引用放到父类的对象中,例如:

A  a;

a=new B();

A  a;

B b=new B();

a=b;

这时,称对象a是对象b的上转型对象。对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。

上转型对象具有如下特点:

  1. 上转型对象不能操作子类新增的成员变量(失去了这部分属性),不能调用子类新增的方法(失掉了这一部分的行为)。
  2. (2)上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。上转型对象操作子类继承的方法或子类重写的实例方法,起作用等价于           子类去调用这些方法。因此,如果子类重写了父类的某个实例方法后,当对象的上转型对象调用这个实例方法时一定是调用了子类重写的实例方法。
  3. 如果子类重写了父类的静态方法,那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法。

问:以下关于类模板描述正确的是()

A. 模板参数只能使用class定义

B. 类模板中不能定义静态数据成员

C. 模板参数只能是类类型

D. 模板参数名不能与模板中自定义类型或类的名字相同

答:D

分析:本题中3个选项是对模板参数的描述。对于模板参数,如果参数是类类型,可以使用class或者typename关键字类定义,所以选项A是不正确的,模板参数除了是类类型,还可以是其他数据类型,例如整型。例如,类模板中需要根据模板参数确定缓存的大小,就需要设计一个整型的模板参数,所以选项C也是不正确的。在类模版中可以像普通类一样定义静态数据成员,使得某一类的实例化模板可以共享数据,因此选项B也是错误的。只有选项D是正确的。因为,如果参数名与模板中自定义类型同名,在类模板中定义的成员将无法确定具体是哪个类型。观察代码:

template <class Type>

class CList

{

private:

typedef int Type;

Type *m_pHeader;

};

C++面试题-面向对象-多态性与虚函数相关推荐

  1. 头歌C++面向对象 - 类的多态性与虚函数

    C++ 面向对象 - 类的多态性与虚函数 一.实训目的 1.掌握虚函数的基本使用. 2.掌握虚析构函数的使用. 3.掌握纯虚函数和抽象类的使用. 二.实训内容 1.人与复读机 设计人类.英语学生类和复 ...

  2. C++(23)--多态性与虚函数

    多态性与虚函数 1.静态多态-重载 2.动态多态-重写 2.1 向上转换/向下转换 3.虚函数的工作原理 4.纯虚函数和抽象类 5.补充项目(都市浮生记)-卒 <老九学堂C++课程>学习笔 ...

  3. C++ 的多态性与虚函数

    腾讯二面时被问到关于C++的多态性和虚函数,当时脑袋发热没回答好,其实根本原因是这是很久之前看的,而且一直没有应用上,所以理所当然说不出个所以然来.趁着国庆假期,把C++草草捡了些回来,现在主要说下多 ...

  4. C++ 多态性和虚函数

    多态性是指当类之间存在层次结构,并且类之间是通过继承关联时,此时调用成员函数,会根据调用函数的对象的类型来执行不同的函数. 多态性可分为静态多态性和动态多态性: 静态多态性,通过函数重载实现,在编译时 ...

  5. C++ 面向对象 - 类的多态性与虚函数

    任务描述 本关任务:设计人类.英语学生类和复读机类三个类. 相关知识 为了完成完成本关任务,你需要掌握虚函数的基本使用. 多态性 在面向对象的方法中,多态性是指向不同对象发送同一个消息,不同对象在接收 ...

  6. c++面向对象程序设计基础教程————多态性和虚函数

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 继承性反映的是类与类之间的层次关系,多态性则是考虑这种层次关系以及类自身特定成员函数之间的关系来解决行为的再抽象问题. ...

  7. C++之多态性与虚函数

    面向对象程序设计中的多态性是指向不同的对象发送同一个消息,不同对象对应同一消息产生不同行为.在程序中消息就是调用函数,不同的行为就是指不同的实现方法,即执行不同的函数体.也可以这样说就是实现了&quo ...

  8. C++面试题:多态,虚函数,纯虚函数

    多态:是对于不同对象接收相同消息时产生不同的动作.C++的多态性具体体现在运行和编译两个方面:在程序运行时的多态性通过继承和虚函数来体现: 在程序编译时多态性体现在函数和运算符的重载上: 开课吧广场C ...

  9. php c++多态区别,【总结】C++多态性与虚函数

    面向对象理论中的3个术语:对象.方法和消息.对象(object):不言而喻,它是构成系统的基本单位,有属性和行为两个要素,在C++中,每个对象都是由数据和函数这两部分组成的,数据即是对象的属性,行为称 ...

最新文章

  1. 2022-2028年中国K酸行业发展现状及前瞻分析报告
  2. iPhone 7 256GB版停售原因分析
  3. java实现生产者消费者问题(转)
  4. Binder Driver浅析:Binder线程池
  5. C++之编码问题(Unicode,ASCII,本地默认)
  6. Oracle PL/SQL编程之过程
  7. AUTOSAR专业知识篇(八)-ID.3 和大众的电气化平台
  8. java 线程强制停止线程_java多线程之停止线程
  9. leetcode python3 简单题171. Excel Sheet Column Number
  10. 学习java 第三天 数据类型以及存储大小取值范围 (one 大白 (●—●))
  11. IIS的Server Application Error报错解决方法
  12. head first 设计模式(限量珍藏版)挂图
  13. 安装 | MATLAB2018a (64位) 安装教程及安装包下载链接
  14. WPF中StackPanel的尺寸的怪癖
  15. ios12怎么滑屏解锁_iOS12.2 越狱来袭,又是一波秀
  16. 解析京东大数据下高效图像特征提取方案
  17. Vue 国家省市三级联动
  18. 大数据分析实战之异构数据源联合分析业务创新实践
  19. 会议排座位系统图书馆座位预约系统哪个好?
  20. 按例学construct2_滚动背景制作 (一)

热门文章

  1. C++ 引用计数技术简介(1)
  2. 使用IDEA在Maven中创建MyBatis逆向工程以及需要注意的问题(入门)
  3. 输入一组数,找出满足某条件的数
  4. 41.字符串函数(三)
  5. C# Socket 简易的图片传输
  6. Ubuntu 10不能通过改source.list装JDK 1.6
  7. asp.net core 系列 17 通用主机 IHostBuilder
  8. Python rsa 加密
  9. Linux stat命令和AIX istat命令 (查看文件修改时间)
  10. linux用户管理的命令及手动添加用户