首页 > 代码库 > 第五十课、c++对象模型分析(上)
第五十课、c++对象模型分析(上)
一、c++对象模型之成员变量
1、class是一种特殊的struct
(1)、在内存中class依旧可以看做是变量的集合
(2)、class与struct遵循相同的内存对齐规则
(3)、class中的成员函数和成员变量是分开存储的
A、每个对象有独立的成员变量
B、所有对象共享类中的成员函数
2、运行时的对象退化为结构体的形式
(1)、所有成员变量在内存中依次分布
(2)、成员变量间可能存在内存间隙
(3)、可以通过内存地址直接访问成员变量
(4)、访问权限关键字在运行时失效
#include<iostream> 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 { int i; int j; char c; double d; }; int main() { A a; cout << "sizeof(A) = " << sizeof(A) << endl;//4+4+4+8=20 cout << "sizeof(a) = " << sizeof(a) << endl;//20 cout << "sizeof(B) = " << sizeof(B) << endl;//20 a.print(); B *p = reinterpret_cast<B*>(&a);//强制转换成结构体,重新解释这片内存空间 p->i = 10; p->j = 20; p->c = ‘a‘; p->d = 3.15;//成功改变private的值,说明private只在编译期起作用,运行时失效 a.print(); return 0; } //输出结果 /* sizeof(A) = 20 sizeof(a) = 20 sizeof(B) = 20 i = -1075365380,j = -1219354059,c = p,d = 4.85915e-270 i = 10,j = 20,c = a,d = 3.15 */
二、c++的对象模型之成员函数
1、类中的成员函数位于代码段中
2、调用成员函数时对象地址作为参数隐式传递(this指针保存了对象的地址,所以即使成员函数和成员变量分开存储,成员函数也可以通过对象的地址访问成员变量)
3、成员函数通过对象地址访问成员变量
4、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(1, 2); cout << "sizeof(d) = " << sizeof(d) << endl;//8 cout << "d.getI() = " << d.getI() << endl;//1 cout << "d.getJ() = " << d.getJ() << endl;//2 cout << "d.add(3) = " << d.add(3) << endl;//6 return 0; }
用C语言来模拟从而探寻对象的本质:实际上就是函数与变量分开,变量在类中
//add.h:
#ifndef _ADD_H_ #define _ADD_H_ typedef void Demo; Demo* Demo_create(int i, int j);//构造函数,返回的返回值是void*的原因是为了数据隐藏,外界无法访问,内部需要访问时再进行强制类型转换回来即可 int Demo_GetI(Demo* pThis);//C语言不像c++会隐式传递对象指针,所以调用成员函数时要显示传递对象地址 int Demo_GetJ(Demo* pThis); int Demo_add(Demo* pThis, int value); void Demo_free(Demo* pThis);//析构函数 #endif
//add.c
#include"add.h" #include<malloc.h> struct ClassDemo//定义一个类 { int mi; int mj; }; Demo* Demo_create(int i, int j) { struct ClassDemo* ret = malloc(sizeof(struct ClassDemo)); if(ret != NULL) { ret->mi = i; ret->mj = j; } return ret; } int Demo_GetI(Demo* pThis) { struct ClassDemo* ret = (struct ClassDemo *)(pThis); return ret->mi; } int Demo_GetJ(Demo* pThis) { struct ClassDemo* ret = (struct ClassDemo *)(pThis); return ret->mj; } int Demo_add(Demo* pThis, int value) { struct ClassDemo* ret = (struct ClassDemo *)(pThis); return (ret->mi + ret->mj + value); } void Demo_free(Demo* pThis) { free(pThis); }
//main.c
#include<stdio.h> #include<malloc.h> #include"add.h" int main() { Demo* d = Demo_create(1, 2);//相当于c++的 Demo* d = new Demo(1, 2) printf("Demo_GetI(d) = %d\n", Demo_GetI(d));//1, 相当于d->GetI(); printf("Demo_GetJ(d) = %d\n", Demo_GetJ(d));//2 printf("Demo_add(d,3) = %d\n", Demo_add(d, 3));//6
//d->mi = 100;//无法访问, d再这里是void*型的,不是类类型,需要在类实现那里进行强制类型转换,所以这里很好达到了封装的目的 Demo_free(d); return 0; }
三、小结
1、c++中的类对象在内存布局上与结构体相同
2、成员变量和成员函数在内存中分开存放(本质)
4、访问权限关键字在运行时失效
3、调用成员函数时对象地址作为参数隐式传递
第五十课、c++对象模型分析(上)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。