1. 什么是虚函数表?虚函数表的结构?
带有虚函数的类对象或者存在虚拟继承的类对象中,会有一个指向虚函数表的指针vptr,其指向一的一块内存中保存着当前类所对应的虚函数的地址。这块内存是一张表格,即为虚函数表
下图为类对象中虚函数表的示意图
2. 虚拟继承解决的问题?
虚拟继承即virtual基类。若一个子类派生自多个父类,这些父类又同时派生自另一个相同的祖父类,那么在实例化时,需要实例化多个父类的祖父类,会因为祖父类的内容相同而出现重名而无法实例化。而虚拟继承可以保证,即使多个父类派生自同一个祖父类,在实例化时,也只有一个祖父类被实例化。这个也是钻石结构问题。
3. 在虚拟继承中,对象的结构是怎样的?
在虚函数表的基础上进行扩充,指向虚基类。(不准确,待更新)
4. 什么是编程范式?都有哪些常见的编程范式?
编程范式简单来说就是指一种编程的思想和风格。主流的编程范式有
结构化编程(面向过程),如C语言
面向对象编程,如C++,Java
函数式编程,如Lisp
每种编程范式都有自己的优缺点,现在各种主流语言已经开始支持各种编程范式的融合
5. 多态是如何实现的?有继承关系的对象如果直接赋值可能会导致什么问题?
C++中的多态是通过指针和引用实现,具有虚函数或虚拟继承关系的类可以实现多态。子类对象中的虚函数表在实例化时会与父类的虚函数表不同,因此在调用一个类对象的虚函数时可以实现多态。
有继承关系的对象如果进行直接赋值可能会导致对象内容的切割,丢失部分内容(指子类对象)
6.抽象数据类型和面向对象编程之间有什么区别?
抽象数据类型(ADT)是将数据和对应的操作做成一个集合,而面向对象(OO)中则存在多种可能性,除了要将数据和方法进行封装之外,还有多态。ADT中的数据和方法是单一实体,在编译过程中就已经确定。
7. C++的语法中是如何支持多态的?
1)隐式指针转换,如一个父类指针指向一个子类对象
2)virtual关键字,通过该关键字实现虚函数和虚基类,在运行时确定调用的方法
3)显示指针转换,用dynamic_cast将一个基类指针转换为一个子类指针
8. 多态的主要用途是什么?或者说是优点?
多态的主要用途是经由一组共同的接口来影响类型的封装,也就是说,当类的内容(有新的继承关系)发生变化时,代码无需进行改动
9. 一个类对象所占用的内存可能由哪几部分构成?
非静态数据成员,虚函数表(及指针),数据对其引起的内存占用
10. 指针是如何拥有不同类型的?比如int型指针和指向对象的指针之间是如何区别的?
依靠编译器的解释,在运行过程中,指针就是一个地址,不存在类型
11. 用一个子类对象去初始化一个基类对象时可能导致什么问题?
当一个基类对象被初始化为一个子类对象时,子类对象会被切割以放入较小的基类对象所占的内存中。此时,多态不会起作用
12. 基于对象(OB,Object Based)的程序设计有哪些优缺点?
OB,object-based,基于对象的。内存布局更紧凑,因为不需要虚函数相关所占用内存,执行也更快,因为不需要运行时利用虚函数表,函数调用在编译时已确定。缺点是没有灵活性。