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. CVPR目标检测与实例分割算法解析:FCOS(2019),Mask R-CNN(2019),PolarMask(2020)

    CVPR目标检测与实例分割算法解析:FCOS(2019),Mask R-CNN(2019),PolarMask(2020)1. 目标检测:FCOS(CVPR 2019)目标检测算法FCOS(FCOS: ...

  2. 2.5D Visual Sound:CVPR2019论文解析

    2.5D Visual Sound:CVPR2019论文解析 论文链接: http://openaccess.thecvf.com/content_CVPR_2019/papers/Gao_2.5D_ ...

  3. 计图(Jittor) 1.1版本:新增骨干网络、JIT功能升级、支持多卡训练

    计图(Jittor) 1.1版本:新增骨干网络.JIT功能升级.支持多卡训练 深度学习框架-计图(Jittor),Jittor的新版本V1.1上线了.主要变化包括: 增加了大量骨干网络的支持,增强了辅 ...

  4. Android 小知识点笔记

    获取 view 的位置 View.getLocationInWindow(int[] location) 一个控件在其父窗口中的坐标位置 View.getLocationOnScreen(int[] ...

  5. mybatis学习——日志工厂

    为什么要使用日志工厂? 我们想一下,我们在测试SQL的时候,要是能够在控制台输出 SQL 的话,是不是就能够有更快的排错效率?答案是肯定的,如果一个 数据库相关的操作出现了问题,我们就可以根据输出的S ...

  6. Etcd中Raft joint consensus的实现

    Joint consensus 分为2个阶段,first switches to a transitional configuration we call joint consensus; once ...

  7. QT环境变量设置

    首先找到自己对应的目录 我的如图 还有一个路径 将这两个路径添加到系统变量的Path中

  8. 内核、dns、网卡配置

    升级内核(安装新版软件包) rpm -ivh kernel-3.10.0-123.1.2.el7.x86_64.rpm 二.配置永久IP地址,子网掩码,网关地址   /etc/sysconfig/ne ...

  9. 遇到禁止复制该怎么办?幸好我会Python...

    相信大家都有遇到这种情况(无法复制): 或者是这种情况 以上这种情况都是网页无法复制文本的情况.不过这些对于Python来说都不是问题.今天辰哥就叫你们用Python去解决. 思路:利用pdfkit库 ...

  10. .NET Core/.NET5/.NET6 开源项目汇总6:框架与架构设计(DDD、云原生/微服务/容器/DevOps/CICD等)项目

    系列目录     [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...