第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 ...
随机推荐
- ThreadLocal,Java中特殊的线程绑定机制
在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个 ...
- 高清SDI编码器|上海视涛科技
SDI编码器(E500)简介 SDI编码器(E500)是上海视涛科技出品的高性能SDI编码产品.该SDI编码器是上海视涛电子完全自主研发,并适用于各种SDI信号的编码采集及网络传输的专用硬件设备.可兼 ...
- 基于MATLAB实现的云模型计算隶属度
”云”或者’云滴‘是云模型的基本单元,所谓云是指在其论域上的一个分布,可以用联合概率的形式(x, u)来表示 云模型用三个数据来表示其特征 期望:云滴在论域空间分布的期望,一般用符号Εx表示. 熵:不 ...
- HTML中图片热区的使用
在HTML中有一个具有把图片划分成多个作用区域,并链接到不同网页的标记,那就是 <area>地图作用区域标记. <area>标记主要用于图像地图,通过该标记可以在图像地图中设定 ...
- SharePoint部署工具SPSD
SharePoint Solution Deployer,绝对属于必备的SharePoint工具之一了. 下载,解压这个工具,会有如下的目录(没有Assemblies和DeployGAC.bat)解压 ...
- 在Android Studio中用Gradle添加Robolectric
我们用Robolectric测试的话需要在gradle中进行配置,国内的详细教程太过简易,而且很多是低版本下的配置方案.所以经过本人的仔细摸索,找到了现在高版本中的配置方案,主要还是参考了官网的配置教 ...
- tableview直接滚动至最后一行的问题
tableview直接滚动至最后一行 类似聊天界面,tableview应该直接显示在最后一行,并且不应该有滚动的出现. 在网上查了很久,直接滚动至最后一行很容易实现,有两种方法比较好. 1. 调用sc ...
- Hibernate的各种关联关系
1.有多中映射 方法 //用XML配置时 <mapping resource="com/liugch/bean/Student.hbm.xml" /> //用注解配置时 ...
- C语言异常与断言接口与实现
程序中通常会出现三种错误:用户错误.运行期错误以及异常 欢迎关注我的个人博客:www.wuyudong.com, 更多精彩文章与您分享 标准库函数setjmp和longjmp 在C语言中,标准库函数s ...
- Xcode 编译运行报错: CpResource /user/xxxx/ xxx Directory not empty
之前遇到过相同的问题,总是记吃不记打,踩过的坑后面还会踩进去... 仅以次标记加深一下印象 错误特征RT 确认该类型错误是library或frameWork的search路径问题 首先找到编译错误的路 ...