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. javascript数组排序算法之选择排序

    前言 作为一名程序员数组的排序算法是必须要掌握的,今天来图解----选择排序 选择排序原理 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大) ...

  2. 细粒度语义分割:ICCV2019论文解析

    细粒度语义分割:ICCV2019论文解析 Fine-Grained Segmentation Networks: Self-Supervised Segmentation for Improved L ...

  3. ContOS8 配置MariaDB

    导语: 该篇文章主要记录ContOS8安装MariaDB后的一些配置内容,若想要详细了解安装过程请移步至上一篇博文! 正文: 首先对MariaDB进行相关的简单配置 使用mysql_secure_in ...

  4. springboot——重定向解决刷新浏览器造成表单重复提交的问题(超详细)

    原因:造成表单重复提交的原因是当我们刷新浏览器的时候,浏览器会发送上一次提交的请求.由于上一次提交的请求方式为post,刷新浏览器就会重新发送这个post请求,造成表单重复提交. 解决办法: 将请求当 ...

  5. .Net RabbitMQ实战指南——进阶(二)

    持久化 持久化可以提高RabbitMQ的可靠性,防止异常情况下的数据丢失.RabbitMQ的持久化分为三个部分:交换器的持久化.队列的持久化和消息的持久化. 交换器的持久化通过声明队列时将durabl ...

  6. ES6深拷贝与浅拷贝

    今天小编和大家一起探讨js中深拷贝和浅拷贝,简单一点理解就是,对于引用数据类型,深拷贝是数据引用地址不同,在改变一个数据的时候,不会影响另一个数据.而浅拷贝刚好相反.两个数据引用的是同一个堆内存地址, ...

  7. Django基础之视图层

    内容概要 小白必会三板斧 request对象方法初识 form表单上传文件 Jsonresponse FBV与CBV 内容详细 1 小白必会三板斧 HttpResponse render redire ...

  8. 『动善时』JMeter基础 — 46、使用Badboy工具录制JMeter脚本

    目录 1.使用Badboy录制JMeter脚本 2.使用Badboy参数化配置 3.解决"当前页面的脚本发生错误"提示框 4.总结 1.使用Badboy录制JMeter脚本 打开B ...

  9. 『言善信』Fiddler工具 — 15、使用Fiddler抓取HTTPS请求

    目录 1.Fiddler抓取HTTPS过程 2.拓展:SSL/TLS证书握手原理 3.Fiddler抓取HTTPS原理总结 4.Fiddler抓取HTTPS设置 步骤1:配置证书 步骤2:勾选设置 5 ...

  10. 面试总被问到HTTP缓存机制及原理?看完你就彻底明白了

    前言 Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是必备的知识技能. 但是对于很多前端 ...