C++:抽象类、虚表、绑定

抽象类

  • 纯虚函数
    在虚函数的后面写上 =0
    virtual void test()=0;

  • 抽象类的定义:包含纯虚函数的类

  • 存在的意义:抽离出多个类中的共同方法,放入一个类
    这个类没有实际的作用,不具体

在这里插入图片描述

抽象类特点:

  1. 抽象类不能创建对象,不被继承就没有意义
  2. 抽象类可以创建指针,让这个父类的指针指向子类对象
    因为抽象类是类型,创建指针就只需要4个或8个字节,该指针就可以存放任意对象的地址
  3. 抽象类被继承后,只有重写全部的纯虚函数,子类才能创建对象,否则该子类也是抽象类
  4. 纯虚函数规范了派生类必须重写,更体现出了接口继承
  • 普通函数的继承是一种实现继承,子类继承了父类的具体函数,可以使用函数,继承的是,函数实现。
  • 虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是,接口。

将共性抽出作为父类,但是父类构造出的对象无意义
使用纯虚函数防止类创建对象

虚函数对类的影响

-类中有虚函数,大小会多出4个字节,即使有多个虚函数也是多4个字节

  • 多出的4个字节是在构造对象时完成的,也就是说这4个字节是在构造函数中创建的
    在这里插入图片描述

编译器一定会生成构造的四种情况

  1. 类中有虚函数,
    原因:编译器需要将自己添加的4个字节进行赋值;
  2. 虚拟继承体系中的子类;
  3. 继承中,父类构造函数是默认的,子类没有显式提供构造函数,会为子类生成构造;
    原因:要通过子类构造去调用父类构造。
  4. 类B中有类A的对象,且A有默认构造函数,B没有提供构造
    原因:B类中包含其它类的对象,需要借助B类构造函数调用A类构造初始化成员

含有虚函数的类多出4个字节,就是因为这4个字节是指针类型,指向了一个虚表,该虚表中保存的就是类中虚函数的入口地址

单继承虚表的构建

虚表在编译阶段生成,存储在代码段

什么是虚表:创建对象后,该对象首4个字节的内容,指向的就是虚表

  • 虚表中保存了类中所有虚函数的地址
  • 表中存放顺序是按虚函数在类中声明的次序存放;
  • 虚表是一个函数指针数组,每个元素类型是函数指针,将这个保存虚函数入口地址的变量称为虚表指针;
  • 虚表指针+成员变量就是该类的对象模型;
    在这里插入图片描述

多继承虚表的构建

与单继承不同的是,子类中新增加的虚函数会放在先继承的父类虚表中

在这里插入图片描述

虚表的构建规则

父类虚表的构建规则:

  • 按照虚函数在类中声明的先后顺序,依次放置到虚表中

子类虚表的构建规则:

  1. 将父类虚表中的内容拷贝一份放置到子类虚表中;
  2. 如果子类重写了父类中某个虚函数,则使用子类虚函数地址,替换虚表中相同偏移量位置的父类虚函数
  3. 子类中新增加的虚函数按照其在类中声明的先后顺序,依次放在虚表的最后

整个虚表在vs2013环境下以NULL结束
父子类虚表的共同特点:

  1. 父类和子类永远都是使用各自的虚表
  2. 单继承中,同一个类的多个对象共享一个虚表

如何调用虚表中的虚函数
在这里插入图片描述

改进:在这里插入图片描述

虚函数调用原理

1.如果通过父类的对象调用虚函数,就直接调用父类中的虚函数
void test (A a)

2.如果通过父类的指针或者引用调虚函数
void test(A& a);

  • 先从对象前4个字节中取出虚表地址;
  • 传递this,因为虚函数是成员函数;
  • 从虚表中取出对应虚函数的入口地址,调用该虚函数

动态绑定与静态绑定

  1. 静态绑定又称为前期绑定(早绑定),在程序编译期间确定了程序的行为,也称为静态多态,比如:函数重载
  2. 动态绑定又称后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值