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. TensorFlow Frontend前端

    TensorFlow Frontend前端 TensorFlow前端有助于将TensorFlow模型导入TVM. Supported versions: 1.12 and below Tested m ...

  2. 如何使用Nsight Compute?

    如何使用Nsight Compute? 下图command Line Argunments是指训练或测试命令,Linux下直接用测试或训练命令

  3. postman环境变量配置的详细过程(步骤加截图)

    环境变量的配置 实战:https://www.baidu.com/s?wd=博客园 使用cmd命令模式输入代码:Nslookup www.baidu.com 模拟环境:线上环境14.215.177.3 ...

  4. 读HikariCP源码学Java(二)—— 因地制宜的改装版ArrayList:FastList

    前言 如前文所述,HikariCP为了提高性能不遗余力,其中一个比较特别的优化是它没有直接使用ArrayList,而是自己实现了FastList,因地制宜,让数组的读写性能都有了一定程度的提高. 构造 ...

  5. 【NX二次开发】创建有界平面UF_MODL_create_bplane

    先准备几条曲线如下图所示,我们用这几条线来创建一个有界平面: 效果:  源码: //有界平面 extern DllExport void ufusr(char *param, int *returnC ...

  6. 剑指0ffer59.滑动窗口的最大值

    给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值. 示例: 输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3输出: [3,3,5,5,6,7] ...

  7. 一次性讲清楚spring中bean的生命周期之一:getSingleton方法

    要想讲清楚spring中bean的生命周期,真的是不容易,以AnnotationConfigApplicationContext上下文为基础来讲解bean的生命周期,AnnotationConfigA ...

  8. MetingJS 是如何配合 Aplayer 加载歌单的?

    Meting.js 介绍 Meting.js 依赖 APlayer.js,扩展了 APlayer.js 的功能,能够使 APlayer.js 加载网易云音乐.QQ 音乐.虾米音乐中的歌单. 安装 &l ...

  9. UnityBug之KeyStore

    UnityException: Can not sign the applicationUnable to sign the application; please provide passwords ...

  10. 关于Word转Markdown的工具Writage安装及使用

    简介 Writage是为希望开始编写结构良好的文档,没有时间或不想深入了解 Markdown 语法的详细信息,或者更愿意使用 Word 作为文本编辑器的每个人设计的 下载并安装 安装包地址:https ...