深度探索C++对象模型(一):关于对象

现用C++对象模型

在c++中,有两种类数据成员:static 和 nonstatic;三种类函数成员:static、nonstatic、virtual。

函数都放到代码区,而static成员都放到静态区,因此

c++对象的大小由 nonstatic类数据成员、内存填充和virtual指针决定,其中virtual指针来源于:

  1. virtual function:用以实现动态多态,支持一个有效率的 "执行期绑定"
  2. virtual base class:用以解决多重继承中的内存问题

c++对象模型如下:

注意:

  1. 虚函数表的第一个slot并不是类虚函数地址,而是类的类型信息(用以支持RTTI)。
  2. vptr的初始化由编译器在construct中初始化
  3. vptr的放置顺序C++ standard并未做出规定,但一般放在对象的头部或者尾部(最常见的是放头部);对象中的数据成员按照其申明顺序放置。

编译器程序转换

px->foo();  // 假如foo()是虚函数

// 编译器转换后

px->_vtbl[2];   // 虚函数表其实就是个指针数组

对象模型为:

指针类型

指针类型本质

 以上三个指针,本身没啥区别,都是占据4字节(32位机器)的地址值,其类型主要体现在其 所指object类型上,指针类型会教导编译器如何解释某个特定地址中"内容及空间大小"

给出ZooAnimal的类声明:

pza指针类型为 ZooAnimal,就可以知道其所指对象的大小为(4+8+4),内容如下:

 而void* 指针,只能得到一个空间的起始地址,而空间大小和空间内容都不得而知,所以无法操作object。空间大小和内容是和类型绑定的,所以在进行cast类型转换时,其实就是在对象空间起始地址不变的情况下,更改其内容和大小。

指针类型在本书后面的讲解中,是十分重要的一个概念。

指针类型和多态的关系

定义一个Bear类继承ZooAnimal类

 其可能的内存布局如下:

 可以看出,指针的值相同,但由于类型不同,其所指的子类对象涵盖的空间比父类对象更大。

因此,不能让一个子类类型的指针指向一个父类对象,不然就会非法访问到超出父类对象的空间,引起安全问题。 

但父类类型的指针指向子类对象是常见的(多态)

另外,下面这种写法也是可行的,会将子类的空间切割复制到父类空间中:

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

曾格0

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值