第50课 C++对象模型分析(上)
1. 回归本质
(1)class是一种特殊的结构体
①在内存中class依旧可以看作变量的集合
②class与struct遵循相同的内存对齐规则
③class中的成员函数与成员变量是分开存放的。即每个对象有独立的成员变量,但所有对象共享类中的成员函数。
【编程实验】对象内存布局初探
#include <iostream>
#include <string>
using namespace std;
class A
{
//默认访问权限为private
int i;
int j;
char c;
double d;
public:
void print()
{
cout << "i = " << i << ", "
<< "j = " << j << ", "
<< "c = " << c << ", "
<< "d = " << d << endl;
}
};
struct B
{
//默认访问权限为public
int i;
int j;
char c;
double d;
};
int main()
{
A a;
//class和struct在内存布局上是一样的。大小相同
cout << "sizeof(A) = " << sizeof(A) << endl; //24 bytes
cout << "sizeof(a) = " << sizeof(a) << endl; //24 bytes
cout << "sizeof(B) = " << sizeof(B) << endl; //24 bytes
cout << endl;
a.print();
cout << endl;
B* p = reinterpret_cast<B*>(&a); //将类强制转化结构体
//利用结构体对类的private成员进行赋值(注意是private成员)
//说明class在运行时,private访问权限只在编译期起作用。
p->i = ;
p->j = ;
p->c = 'C';
p->d = 3.14;
a.print(); //class中的private成员被改变
;
}
/*输出结果
sizeof(A) = 24
sizeof(a) = 24
sizeof(B) = 24
i = 4202544, j = 65535, c = , d = 8.69169e-311
i = 100, j = 200, c = C, d = 3.14
*/
(2)运行时的对象退化为结构体的形式
①所有成员变量在内存中依次排布
②成员变量间可能存在内存空隙
③可以通过内存地址直接访问成员变量
④访问权限关键字在运行时失效
2. C++对象模型
(1)类中的成员函数位于代码段中
(2)调用成员函数时对象地址作为参数隐式传递
(3)成员函数通过对象地址访问成员变量
(4)C++语法规则隐藏了对象地址的传递过程
【编程实验】对象本质分析(用C写面向对象)
//C++示例
#include <iostream>
#include <string>
using namespace std;
class Demo
{
int mi;
int mj;
public:
Demo(int i, int j)
{
mi = i;
mj = j;
}
int getI()
{
return mi;
}
int getJ()
{
return mj;
}
int add(int value)
{
return mi + mj + value;
}
};
int main()
{
Demo d(, );
cout <<
cout <<
cout <<
cout << ) << endl;
;
}
//C语言模拟面向对象
//50-2.h
#ifndef _50_2_H_ #define _50_2_H_ typedef void Demo; //声明成员函数(接口) Demo* Demo_Create(int i, int j); int Demo_GetI(Demo* pThis); int Demo_GetJ(Demo* pThis); int Demo_Add(Demo* pThis, int value); void Demo_Free(Demo* pThis); #endif
//50-2.c
#include "50-2.h"
#include <malloc.h>
//利用C语言来实现面向对象
//定义结构体
struct ClassDemo
{
int mi;
int mj;
};
//实现各成员函数(带this指针)
//构造函数
Demo* Demo_Create(int i, int j)
{
struct ClassDemo* ret = (struct ClassDemo*)malloc(sizeof(struct ClassDemo));
)
{
ret ->mi = i;
ret ->mj = j;
}
return ret;
}
int Demo_GetI(Demo* pThis)
{
struct ClassDemo* obj = (struct ClassDemo*)pThis;
return obj->mi;
}
int Demo_GetJ(Demo* pThis)
{
struct ClassDemo* obj = (struct ClassDemo*)pThis;
return obj->mj;
}
int Demo_Add(Demo* pThis, int value)
{
struct ClassDemo* obj = (struct ClassDemo*)pThis;
return obj->mi + obj->mj + value;
}
//析构函数
void Demo_Free(Demo* pThis)
{
free(pThis);
}
//main.c
#include <stdio.h>
#include "50-2.h"
int main(void)
{
Demo* d = Demo_Create(, ); //Demo* d = new Demo(1, 2);
//各函数调用中,传处this指针:d
printf("d.mi = %d\n", Demo_GetI(d)); //d->getI();
printf("d.mj = %d\n", Demo_GetJ(d)); //d->getJ();
printf()); //d->add(3);
//d->mi = 100; //相当于私有变量,不能直接通过this指针(d)来访问
Demo_Free(d);
;
}
3. 小结
(1)C++中的类对象在内存布局上与结构体相同
(2)成员变量和成员函数在内存中分开存放
(3)访问权限关键字在运行时失效
(4)调用成员函数时对象地址作为参数隐式传递
第50课 C++对象模型分析(上)的更多相关文章
- 第50 课C++对象模型分析——成员变量(上)
C++对象模型,其实就是C++中的对象在内存中是如何排布的.C++中的对象包含了成员变量和成员函数,其实就是研究C++中的类对象它的成员变量和成员函数在内存中是如何排布的. 回归本质class 是一种 ...
- 第50 课C++对象模型分析——成员函数(上)
类中的成员函数位于代码段中调用成员函数时对象地址作为参数隐式传递成员函数通过对象地址访问成员变量C++语法规则隐藏了对象地址的传递过程 #include<iostream> #includ ...
- 第51课 C++对象模型分析(下)
1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protec ...
- Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation
原文:Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...
- 第24课 - #pragma 使用分析
第24课 - #pragma 使用分析 1. #pragma简介 (1)#pragma 是一条预处理器指令 (2)#pragma 指令比较依赖于具体的编译器,在不同的编译器之间不具有可移植性,表现为两 ...
- R与数据分析旧笔记(六)多元线性分析 上
> x=iris[which(iris$Species=="setosa"),1:4] > plot(x) 首先是简单的肉眼观察数据之间相关性 多元回归相较于一元回归的 ...
- C++对象模型的那些事儿之一:对象模型(上)
前言 很早以前就听人推荐了<深入理解C++对象模型>这本书,从年初买来到现在也只是偶尔翻了翻,总觉得晦涩难懂,放在实验室上吃灰吃了好久.近期由于找工作对C++的知识做了一个全面系统的学习, ...
- 拥有的50个CSS代码片段(上)
1. CSS 重置 ;;;font-size: 100%; font: inherit; vertical-align: baseline; outline: none; -webkit-box-si ...
- 知识小罐头05(tomcat8请求源码分析 上)
这一篇我们不看源码,就大概理一下Tomcat内部组成部分!前面花费了两篇博客的篇幅来说说了一般的maven web项目并部署到tomcat运行,其实都是为这篇做铺垫的! 其实我下载了tomcat7,t ...
随机推荐
- 如何选择RabbitMQ的消息保存方式?
RabbitMQ对于queue中的message的保存方式有两种方式:disc和ram.如果采用disc,则需要对exchange/queue/delivery mode都要设置成durable模式. ...
- HTML JavaScript的DOM操作
1.DOM的基本概念 DOM是文档对象模型,这种模型为树模型:文档是指标签文档:对象是指文档中每个元素:模型是指抽象化的东西. 2.Window对象操作 一.属性和方法: 属性(值或者子对象): op ...
- 安卓开发_慕课网_ViewPager实现Tab(App主界面)
学习内容来自“慕课网” 网站上一共有4种方法来实现APP主界面的TAB方法 这里学习第一种 ViewPager实现Tab 布局文件有7个, 主界面acitivity.layout <Linear ...
- IOS 杂笔-13(appearance的巧妙使用)
在我们查看原生api时,我们不难发现,有些api的后面有着->UI_APPEARANCE_SELECTOR 那么我可以很高兴的说我们可以通过appearance对象来统一设置.十分巧妙. 例如: ...
- 解决Spring4 MVC请求json数据报406错误
解决方法一: 1.导入jackson-core-2.5.1.jar和jackson-databind-2.5.1.jar 2.Spring配置文件添加: <!-- 避免IE执行AJAX时,返回J ...
- SAM4E单片机之旅——20、DMAC之使用Multi-buffer进行内存拷贝
这次使用这个DMAC的Multi-buffer传输功能,将两个缓冲区的内容拷贝至一个连续的缓冲区中. 一. DMAC 在M4中,DMA控制器(DMAC)比外设DMA控制器(PDC)要复杂,但是功能更加 ...
- android之旋转的刻度盘
这是在学习android的Canvas绘图技巧时做的一个实例.主要用的核心方法就是canvas.save,canvas.rotate, canvas.translate以及canvas.restore ...
- Effetive Java 22 Favor static member classes over nonstatic
Nested class types Usage and remark Advantage Disadvantage static member classes Use for public help ...
- JavaScript Patterns 4.5 Immediate Functions
The immediate function pattern is a syntax that enables you to execute a function as soon as it is d ...
- 方程ax2+bx+c=0;一元二次方程。求根
<body>方程ax2+bx+c=0;一元二次方程.求根请输入a:<input type="number" id="a"/><br ...