第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 ...
随机推荐
- C++之内联函数与constexpr
inline 函数 规模小,流程直接且频繁调用 cout<<shortString(s1,s2)<<endl; = cout<<(s1.size()<s2.s ...
- sqlserver允许远程连接的配置
如果无法通过IP地址远程连接你服务器上的SQL Server服务器,可以参考下面的内容进行设置 在进行下述设置之前,应该确保你的网络已经安装设置完毕,服务器已经正常连接到网络中. 1.单击Window ...
- ASP.NET验证码生成与识别
一般验证码页面只输出一个图片而不进行其他业务处理,所以验证码一般放在一般处理程序(httpHandler)页面中,而如果将验证码生成代码放到一般处理程序中,要将生成验证码保存在Session中,这里我 ...
- andriod 获得drawable下所有图片
package com.example.yanlei.my1; import android.app.AlertDialog; import android.content.Context; impo ...
- Windows Python2.7环境 安装paramiko模块
Paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 举个常见的例子,现有这样的需求:远程连接到Linux服务器,查看上面的日志状态,大家 ...
- 部分博文目录索引(C语言+算法)
今天将本博客的部分文章建立一个索引,方便大家进行阅读,当然每一类别中的文章都会持续的添加和更新(PS:博文主要使用C语言) 博客地址:http://www.cnblogs.com/archimedes ...
- 【读书笔记】iOS-简单的数据驱动程序
一,效果图. 二,,工程文件如下图所示: 三,DataModel.h #import <Foundation/Foundation.h> @interface DataModel : ...
- Silverlight项目笔记5:Oracle归档模式引起的异常&&表格控件绑定按钮
1.Oracle归档模式产生日志文件引起数据库异常 连接数据库失败,提示监听错误,各种检查监听配置文件,删除再添加监听,无果. sqlplus下重启数据库数据库依然无果,期间碰到多个错误提示: ORA ...
- iOS设计模式 - 单例
备注:只能通过类的类方法才能创建单例类的实例,[[类名 alloc]init]创建实例没有用的. 原理图 说明 1. 单例模式人人用过,严格的单例模式很少有人用过 2. 严格的单例模式指的是无法通过常 ...
- MAC OS Finder 中快速定位指定路径
在看一些 tip 文章的时候,时不时会有需要进到某某目录替换文件之类的步骤.如果碰上这个目录层次够多,一层一层的点击既麻烦又容易出错,有什么快捷的办法呢? 快捷键:Shift + Command + ...