C++对象模型 笔记1

C++类中的函数不会占用类本身的内存,而是类的声明的非内联函数只会诞生一个函数体。C++在布局和存取时间上主要的额外负担由virtual引起:

  • virtual function机制 执行期动态绑定
  • virtual base class机制 多次继承中,单一的基类被共享

C++的基本面向对象模型:

  • 所有的非静态数据成员存放到class内部
  • 静态成员和函数存放到class外部

虚函数的支持步骤:

  • 每个class产生一些指向virtual function的指针,存放在一个表格中,称为虚表,virtual tablevtbl
  • 每个class添加一个指针,指向相关的vtbl,称为vptr

该方式的好处是空间和存取时间效率高,缺点在于如果程序代码没变,但是class的非静态成员改变了,那么代码就要重新编译。

虚拟继承情况下,不管发生多少次继承,永远只有一个基类。可以理解为一个bptr,有点在于减少二义性,缺点在于时空表现的效率低。

C++支持多态的方式,仅仅使用下列方法是安全的:

  • 使用指针的操作,子类的指针可以指向基类:

    shape *ps = new circle();  // circle是shape的子类
    
  • 使用virtual function机制:

    ps->rotate();   // 调用实际的函数
    
  • 使用dynamic_casttypeid运算符:

    if (circle *pc = dynamic_cast<circle*>(ps) ) ...
    

多态最主要的用法是使用共同的接口进行封装,一般来说这个接口定义在一个抽象的基类中。这就像Java的interface关键字,不过C++没有接口的具体关键字,实际中可以使用多重继承虚基类来完成,在运行期进行检查到底是执行哪一个子类的函数。

动态绑定操作会在传入引用和指针的时候发生。

一个class object占用内存的大小取决于下面三个:

  • 非静态成员总和的大小
  • 需要alignment的需求而padding的空间
  • 为了支持virtual而产生的空间,主要是各种虚表。对于指针(不包含智能指针)来说,它们占用的内存大小是固定的。

如果把子类转换成基类,那么子类会被切割,只保留基类的部分。

只有下面4种情况下,才会有自动生成的默认构造函数:

  • 如果一个class没有构造函数,而它的成员含有默认构造函数,此时会产生一个构造函数,不过合成操作只有真正需要调用时才会发生。
  • 基类由默认构造函数,派生类没有定义构造函数,此时会合成一个默认构造函数,而且会调用基类的构造函数,根据声明的次序执行
  • 带有virtual functionclass。 当一个class声明(或继承)一个virtual functionclass派生自一个继承串链,其中有一个或者多个虚基类
  • 带有虚基类的类

必须使用参数初始化列表的情况:

  • 初始化引用对象
  • 初始化const对象
  • 调用基类的构造函数,且构造函数拥有一组参数
  • 调用类成员的构造函数,而且有参数

初始化列表的顺序不一定按照声明的顺序执行,这点要格外注意!!!一般来说,很多时候初始化列表的效率更高,因此在意义明确的情况下,尽量使用初始化列表!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值