Geekband-job2.1-note

1、C++对象在内存中的布局

在vs2013+win10环境下,数据的对齐为8个字节。

当某个基类有虚函数时,这个类生成一个表格,称为虚表(virtual table,简称vtbl)。虚表中存放着一堆指针,这些指针指向该类每一个虚函数。虚表中的函数地址将按声明时的顺序排列。每个类对象都拥有一个虚表指针(vptr),由编译器为其生成。虚表指针的设定与重置皆由类的复制控制(也即是构造函数、析构函数、赋值操作符)来完成。vptr的位置为编译器决定,传统上它被放在所有显示声明的成员之后,不过现在许多编译器把vptr放在一个类对象的最前端。另外,虚函数表的前面设置了一个指向type_info的指针,用以支持RTTI(Run Time Type Identification,运行时类型识别)。RTTI是为多态而生成的信息,包括对象继承关系,对象本身的描述等,只有具有虚函数的对象在会生成。对象的数据则接着vprt,对齐方式为8个字节。


当该类为子类时,对象的首地址存放vptr,若子类重写(overwrite)了父类的虚函数,则子类虚函数将覆盖父类虚表中对应的函数;若子类并无overwrite父类虚函数,而是声明了自己新的虚函数,则该虚函数地址将扩充到父类虚函数表最后(在vs中无法通过监视看到扩充的结果,不过我们通过取地址的方法可以做到,子类新的虚函数确实在父类子物体的虚函数表末端)。接着是基类的数据,最后是子类的自己定义的数据。


取址的方式如下:

cout << "虚函数表第一个函数的地址:" << (int *)*((int*)(&p)) << endl;

cout << "析构函数的地址:" << (int* )*(int *)*((int*)(&p)) << endl;

cout << "虚函数表中,第二个虚函数即print()的地址:" << ((int*)*(int*)(&p) + 1) << endl;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 题目类型 a.C++与C差异(1-18) 1.C和C++中struct有什么区别? C没有Protection行为...
    阿面a阅读 7,769评论 0 10
  • const 引用 const 引用是指向 const 对象的引用:const int ival = 1024;co...
    rogerwu1228阅读 674评论 0 1
  • 第一章 计算机与C++编程简介 C++程序6个阶段编程 ->预处理->编译->连接->装入->执行1.程序在编译器...
    rogertan30阅读 4,220评论 0 1
  • 上篇请看:C++编程思想重点笔记(上) 宏的好处与坏处 宏的好处:#与##的使用 三个有用的特征:字符串定义、字符...
    小敏纸阅读 660评论 0 2
  • C++ 面向对象编程 博客园地址:http://www.cnblogs.com/xiongxuanwen/p/42...
    先之阅读 693评论 0 1