C++多态细节,反汇编

文章目录

  • 1.C++的三大特性
    • 1.1封装
    • 1.2继承
    • 1.3多态
      • 1.3.1 虚函数
      • 1.3.1.1.【注意】当类存在虚函数时,编译器会为类创建一个虚表,虚表是一个数组,数组的元素存放的是虚函数地址。即虚表在编译的时候就确定了,且只有一份。同时为每个类对象添加一个隐藏数据成员,即虚表指针,它是在运行阶段确定的,有多少个对象,就有多少个虚表指针。另外,虚表指针被定义在对象首地址处。
      • 1.3.1.2.【注意】派生类会生成兼容基类的虚表,如果子类重写了相应的虚函数,那么子类虚表中相应的虚函数地址就会改变,指向自身的虚函数实现,否则指向的是基类的虚函数实现。另外,如果子类也有虚函数,那么子类虚表就会添加该虚函数地址。
      • 1.3.1.3.【注意】每个类都有虚表时,单继承的子类维护一张虚表,子类对象有一个虚表指针。多继承的子类维护多张虚表,子类对象包含多个虚表指针。
      • 1.3.1.4. 为什么构造函数通常不定义为虚函数?
      • 1.3.1.5. 引用是否能实现动态绑定?
      • 1.3.2 多态代码+反汇编分析。
        • 反汇编分析1——基类指针指向子类对象,构造过程。
        • 反汇编分析2——基类指针指向子类对象,调用虚函数getPrice()过程。
        • 反汇编分析3——基类对象,调用虚函数getPrice()过程。
        • 反汇编分析4——基类指针指向子类对象,析构过程。
        • 反汇编分析5——基类指针指向子类对象,析构过程,基类析构函数不是虚函数时。
      • 1.3.3 静态多态vs动态多态

1.C++的三大特性

1.1封装

将对象的属性和方法封装起来。为了模块化,便于使用者操作,同时可以隔离外部使用者对内部数据的干扰,提高了安全性。

类成员的三种属性:
private:本类使用。设置get和set方法,因为通过接口来访问和修改数据是可控的,相对安全。
protected:本类和子类使用。
public:公开的,都可以访问。

1.2继承

允许通过继承原有类的某些特性或全部特性而产生新的类,原有的类称为基类(父类),产生的类称为派生类(子类)。为了扩展和重用,减少重复代码。

1.3多态

发生在继承关系中,不同的对象,对于相同的方法有不同的操作逻辑。为了接口重用,提高代码的可复用性、可维护性和可扩充性。

多态的实现机制为虚函数。

1.3.1 虚函数

关键字:virtual

作用:允许在子类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和子类的同名函数。

最常见的用法:声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。

实现原理:虚表+虚表指针。

1.3.1.1.【注意】当类存在虚函数时,编译器会为类创建一个虚表,虚表是一个数组,数组的元素存放的是虚函数地址。即虚表在编译的时候就确定了,且只有一份。同时为每个类对象添加一个隐藏数据成员,即虚表指针,它是在运行阶段确定的,有多少个对象,就有多少个虚表指针。另外,虚表指针被定义在对象首地址处。

1.3.1.2.【注意】派生类会生成兼容基类的虚表,如果子类重写了相应的虚函数,那么子类虚表中相应的虚函数地址就会改变,指向自身的虚函数实现,否则指向的是基类的虚函数实现。另外,如果子类也有虚函数,那么子类虚表就会添加该虚函数地址。

1.3.1.3.【注意】每个类都有虚表时,单继承的子类维护一张虚表,子类对象有一个虚表指针。多继承的子类维护多张虚表,子类对象包含多个虚表指针。

1.3.1.4. 为什么构造函数通常不定义为虚函数?

  • 虚函数的调用需要虚表指针,而该指针存放在对象的内存空间中。由于初始时,对象还未创建,还没有内存空间,更没有虚表指针用来调用虚构造函数。

1.3.1.5. 引用是否能实现动态绑定?

  • 可以,因为引用或指针既可以指向基类对象也可以指向子类对象,所以它是在运行时根据所指对象,调用相应的虚函数。

1.3.2 多态代码+反汇编分析。

1.基类Shape,数据成员为price和area,虚析构函数,两个虚函数为getDescribe()和getPrice(),;
2.子类Circle,继承Shape,数据成员为radius,重写父类方法getPrice();
3.main()里,基类指针s1指向Circle类对象,基类对象s2。代码如下。

#include
using namespace std;


class Shape
{
   
protected:
    double price;
    double area;

public:
    Shape() :price(100), area(

你可能感兴趣的:(C++细节,c++,面试,笔记)