1 对象模型的前世

  类在c++编译器内部可以理解成结构体,所以在对象模型分析时,我们可以把 class  当作一种特殊的 struct;

  1)在内存中 class 可以看作是普通成员变量的集合;

  2)class 与 struct 遵循相同的内存对齐规则;

  3)class 中的 成员变量 与 成员函数 是分开存放的;

    1. 每个对象都有独立的成员变量;成员变量可以存储在 栈空间、堆空间、全局数据区;

    2. 所有对象共享类的成员函数;成员函数 只能存储在 代码段;

      理解下面这 3 句话:(对象地址 == this指针)

        1、成员函数通过对象地址访问成员变量;

        2、调用成员函数时将对象地址作为参数隐式传递;

        3、c++语法规则隐藏了对象地址的传递过程;

  4)访问权限关键字在运行时失效;(外界访问类的私有成员时只在编译阶段有效)

  注:若没有明确说是 static 成员时,默认都是 普通成员;    

  代码分析:

 1 #include <iostream>
2 #include <string>
3
4 using namespace std;
5
6 #pragma pack(push, 4) // 将数据存储方式设置为 压栈方式,字节对齐方式 设置为 4
7
8 class A
9 {
10 static int count; // 静态成员变量在类的外部单独分配空间,静态成员变量在程序内部位于 全局数据区
11 char *pt; // 8 bytes(OS:64bit)
12 char c; // 1 bytes
13 int i; // 4 bytes
14 double d; // 8 bytes
15 public:
16 A(const char *pt = NULL, char c = ' ', int i = 0, double d = 0)
17 {
18 this->pt = new char(' ');
19 this->c = ' ';
20 this->i = i;
21 this->d = 0;
22 }
23 void print()
24 {
25 cout << "*pt = " << *pt << ", "
26 << "c = " << c << ", "
27 << "i = " << i << ", "
28 << "d = " << d << endl;
29 }
30 ~A()
31 {
32 delete pt;
33 }
34 };
35
36 int A:: count = 0;
37
38 struct B
39 {
40 char *pt; // 8 bytes(OS:64bit)
41 char c; // 1 bytes
42 int i; // 4 bytes
43 double d; // 8 bytes
44 };
45
46 #pragma pack(pop)// 恢复压栈前的设置
47
48 int main()
49 {
50 A a;
51
52 cout << "sizeof(a) = " << sizeof(a) << endl; // 24 bytes
53 cout << "sizeof(A) = " << sizeof(A) << endl; // 24 bytes
54 cout << "sizeof(B) = " << sizeof(B) << endl; // 24 bytes
55
56 a.print(); // *pt = , i = 0, c = , d = 0
57
58 B* p = reinterpret_cast<B*>(&a); // struct 与 class 的内存模型相同
59
60 *(p->pt) = 'P';
61 p->c = 'C';
62 p->i = 100;
63 p->d = 3.14;
64
65 a.print(); // *pt = P, i = 100, c = C, d = 3.14
66
67 return 0;
68 }

单个类对象的内存模型练习

 1 // demo.h
2
3 #ifndef _DEMO_H_
4 #define _DEMO_H_
5
6 typedef void Demo;
7
8 Demo* demo_Create(int i, int j); // 等价于 c++ 构造函数 Demo(int i, int j)
9 int demo_getI(Demo *pThis); // 等价于 c++ 成员函数 int getI()
10 int demo_getJ(Demo *pThis); // 等价于 c++ 成员函数 int getJ()
11 int demo_add(Demo *pThis, int value); // 等价于 c++ 成员函数 int add(int value)
12 Demo demo_free(Demo *pThis); // 等价于 c++ 析构函数 ~Demo()
13
14 #endif
15
16 // demo.c
17 #include "demo.h"
18 #include "malloc.h"
19
20 typedef struct DemoStruct
21 {
22 int i;
23 int j;
24 } DemoStruct;
25
26 Demo* demo_Create(int i, int j)
27 {
28 DemoStruct *this = (DemoStruct*)malloc( sizeof(DemoStruct) );
29
30 if(this != NULL)
31 {
32 this->i = i;
33 this->j = j;
34 }
35
36 return this;
37 }
38
39 int demo_getI(Demo *pThis)
40 {
41 DemoStruct *this = (DemoStruct*)pThis;
42
43 return this->i;
44 }
45
46 int demo_getJ(Demo *pThis)
47 {
48 DemoStruct *this = (DemoStruct*)pThis;
49
50 return this->j;
51 }
52
53 int demo_add(Demo *pThis, int value)
54 {
55 DemoStruct *this = (DemoStruct*)pThis;
56
57 return (this->i + this->j + value);
58 }
59
60 Demo demo_free(Demo *pThis)
61 {
62 DemoStruct *this = (DemoStruct*)pThis;
63
64 free(this);
65 }
66
67 // mian.c
68
69 #include "stdio.h"
70 #include "demo.h"
71
72 int main(int argc, char const *argv[])
73 {
74 Demo *d = demo_Create(10, 20); // 相当于 c++中的 Demo* d = new Demo(10, 20);
75
76 int i = demo_getI(d); // 相当于 c++中的 d->getI();
77 int j = demo_getJ(d); // 相当于 c++中的 d->getJ();
78 int v = demo_add(d, 30); // 相当于 c++中的 d->add(30);
79
80 printf("i = %d, j = %d, v = %d\n", i, j, v); // i = 10, j = 20, v = 60
81
82 // d->i = 11; // err, 相当于 c++的private属性
83
84 demo_free(d);
85
86 return 0;
87 }

用c语言复现c++中的this指针

补充:字节对齐知识点

 1 /*
2 #pragma pack(push, 4) 《=》
3 #pragma pack(push)
4 #pragma pack(4)
5 */
6 #pragma pack(push, 4) // 将数据存储方式设置为 压栈方式,字节对齐方式 设置为 4
7 struct S
8 {
9 char c;
10 int i;
11 };
12 #pragma pack(pop) // 恢复压栈前的设置
13
14 #pragma pack (4) //作用:C编译器将按照4个字节对齐。
15 struct S
16 {
17 char c;
18 int i;
19 }
20 #pragma pack () // 作用:取消自定义字节对齐方式

c/c++字节对齐方式设置

2 继承中的对象模型

  子类是由父类成员叠加子类中的新成员形成的。

    

c++中的对象模型的更多相关文章

  1. Qt 中的对象模型(Object Model)

    原标题:Qt 中的对象模型(Object Model)90不太后,余生皆折腾 本节内容主要讲了 Qt 对象模型比标准 C++ 对象模型多了什么内容,并介绍了组成 Qt 对象模型基础的相关的类.最后说明 ...

  2. C++ //继承中的对象模型 //利用开发人员命令提示工具查看对象模型 //父类中所有非静态成员属性都会被 子类继承下去 //父类中私有成员属性 是被编译器给隐藏了 因此是访问不到 但是确实被继承下去了

    1 //继承方式 2 //语法:class 子类 :继承方式 父类 3 //继承方式 三种: 4 //1.公共继承 5 //2.保护继承 6 //3.私有继承 7 8 /* 9 #include &l ...

  3. ZeroC ICE中的对象模型和概念

    Ice对象的模型和概念. Ice Object并非是我们的接口实现类的实例对象.我们的接口实现类的实例对象只是充当Ice Object的Servant的角色.一个Ice Object可以有众多Serv ...

  4. QT中的对象模型――QPointer

    QPointer是一个模板类,为QObject对象提供了守卫指针(Guarded Pointer).什么是守卫指针?守卫指针QPointer<T>类似于普通C++指针T *,有且仅有一点不 ...

  5. 浅谈Excel开发:三 Excel 对象模型

    前一篇文章介绍了Excel中的菜单系统,在创建完菜单和工具栏之后,就要着手进行功能的开发了.不论您采用何种方式来开发Excel应用程序,了解Excel对象模型尤其重要,这些对象是您与Excel进行交互 ...

  6. [MSDN] 使用 SharePoint 2013 中的 JavaScript 库代码完成基本操作

    MSDN:http://msdn.microsoft.com/zh-cn/library/jj163201.aspx 了解如何编写代码以在 SharePoint 2013 中使用 JavaScript ...

  7. 转载:Python中的new style class机制实现

    1.Python中的对象模型python中所有东西都是对象 class对象:表示Python内置的类型和定义的类型instance对象(实例对象):表示由class对象创建的实例 1.1 对象间的关系 ...

  8. Thinking in UML 学习笔记(一)——建立对象模型

    一.面向对象的本质 面向对象的本质是抽象,当系统达到了超越其处理能力的程度,我们能够抽象出我们能够处理的范围来提成抽象级别,这样就能够构建更大.更复杂的系统. 现实世界和对象世界之间存在着一道沟壑,这 ...

  9. C++中的类继承(4)继承种类之单继承&多继承&菱形继承

    单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承.这种继承方式使一个子类可 ...

随机推荐

  1. Python+Selenium - 浏览器驱动

    Chrome \ Firefox 下载浏览器版本对应的驱动文件后,放在D:\Program Files (x86)\Python\Python38路径下,Python使用时用 driver = web ...

  2. pytorch生成对抗示例

    pytorch生成对抗示例 本文对ML(机器学习)模型的安全漏洞的认识,并将深入了解对抗性机器学习的热门话题.图像添加难以察觉的扰动会导致模型性能大不相同.通过图像分类器上的示例探讨该主题.使用第一种 ...

  3. 3D-LiDAR

    3D-LiDAR 结合光学+激光扫描+数据处理技术,实现对人和物体的无盲点检测. 利用专有光学技术实现高精度,高分辨率三维扫描. 到目前为止,传感器只能准确地检测出物体的存在,而且很难感知目标的大小和 ...

  4. RGB Color Codes Chart

    RGB Color Codes Chart RGB颜色空间 RGB颜色空间或RGB颜色系统,从红色.绿色和蓝色的组合中构造所有颜色. 红色.绿色和蓝色各使用8位,它们的整数值从0到255.这使得256 ...

  5. 为IHttpClientFactory添加动态命名配置

    某些时候我们需要为HttpClient动态配置一些东西, 例如证书等, 参考博问 如何使用IHttpClientFactory动态添加cer证书. 例如服务是一个回调服务, 而被回调方采用了自定义的h ...

  6. SpringCloud 面试题 (持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  7. spring赌上未来的一击:WebFlux性能实测

    最近花了一点时间系统的测试验证了在SpringBoot框架下使用SpringMVC和Spring WebFlux两种框架开发接口,对比了响应时间以及压测吞吐量的区别. WebFlux&Spri ...

  8. 用好idea这几款插件,可以帮你少写30%的代码

    Easycode是idea的一个插件,可以直接对数据的表生成entity,controller,service,dao,mapper,无需任何编码,简单而强大. 1.安装(EasyCode) 我这里的 ...

  9. 「10.14」小P的2048(模拟)·小P的单调数列(性质,DP)·小P的生成树(乱搞)

    A. 小P的2048 模拟.....又没啥可说的,以后要认真打打模拟题了... B. 小P的单调数列 考场$n^2log(n)$的SB思路有人听吗 正解当然不是这样, 事实上我们每次选取的只有一段区间 ...

  10. Redis客户端管理

    1.客户端管理 Redis提供了客户端相关API对其状态进行监控和管理,本节将深入介绍各个API的使用方法以及在开发运维中可能遇到的问题. 1.1 客户端API 1.client list clien ...