c++八股之多态(持续更新)

ysysys

c++多态

  • c++的多态,从绑定时间来看,可以分为静态多态动态多态,或者说是编译期多态运行时多态
  • 范型编程和模板编程通过模板的机制实现静态多态
  • 对象模型通过重载虚函数的机制实现静态多态和动态多态
1. inliine函数可以是虚函数码?

不可以,因为inline函数没有地址,无法将他存放到虚函数表中。

2. 静态成员可以是虚函数吗?

不能,因为静态成员函数中没有this指针,使用::的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。

3. 构造函数可以是虚函数吗?

不可以,因为对象中的虚函数指针是在对象构造的时候初始化的。

4. 析构函数可以是虚函数吗?什么场景下析构函数是虚函数?

cppreference:一条有用的方针是,任何基类的析构函数必须为公开且虚,或受保护且非虚
这个问题也就是说,是否应该允许指向基类的指针进行销毁派生类对象?如果是,则base的析构函数必须是公共的才能被调用,否则虚拟调用它会导致未定义的行为。否则,应该对其进行保护,以便只有派生类才能在自己的析构函数中调用它,这个析构函数也应该是非虚的,因为它不需要虚拟地运行。

5. 对象访问普通函数快还是虚函数快?

如果是普通对象,是一样快的,如果是指针对象或者是引用对象,调用普通函数更快一些,因为构成了多态,运行时调用虚函数要先到虚函数表中去查找。这样然后才拿到函数的地址,这样就不如直接可以拿到函数地址的普通函数快。

6.虚函数表指针被编译器初始化的过程怎么理解的?

当类中声明了虚函数是,编译器会在类中生成一个虚函数表VS中存放在代码段,虚函数表实际上就是一个存放虚函数指针的指针数组,是由编译器自动生成并维护的。虚表是属于类的,不属于某个具体的对象,一个类中只需要有一个虚表即可。同一个类中的所有对象使用同一个虚表,为了让每个包含虚表的类的对象都拥有一个虚表指针,编译器在每个对象的头添加了一个指针,用来指向虚表,并且这个指针的值会自动被设置成指向类的虚表,每一个virtaul函数的函数指针存放在虚表中,如果是单继承,先将父类的虚表添加到子类的虚表中,然后子类再添加自己新增的虚函数指针,但是在VS编译器中我们通常看不到新添加的虚函数指针,是编译器故意将他们隐藏起来,如果是多继承,在子类中新添加的虚函数指针会存放在第一个继承父类的虚函数表中。

7. 多态的分类

静态绑定的多态的是通过函数的重载来实现的。动态绑定的多态是通过虚函数实现的。

8. 为什么要引入抽象类和纯虚函数?

在很多情况下由基类生成对象是很不合理的,纯虚函数在基类中是没有定义的,要求在子类必须加以实现,这种包含了纯虚函数的基类被称为抽象类,不能被实例化,如果子类没有实现纯虚函数,那么它他也是一个抽象类。

9. 虚函数和纯虚函数有什么区别?

纯虚函数不在基类里实现,必须要在派生类里重写。
非纯虚函数,可以在基类实现,派生类可以实现,也可以不重写
虚函数既继承接口的同时也继承了基类的实现,纯虚函数关注的是接口的统一性,实现完全由子类来完成。

阅读 119
7 声望
0 粉丝
0 条评论
你知道吗?

7 声望
0 粉丝
宣传栏