第50课 C++对象模型分析(上)
2018-01-21 14:31
363 查看
1、回归本质
1.1、class是一种特殊的结构体1.1.1、在内存中class依旧可以看作变量的集合
1.1.2、class与struct遵循相同的内存对齐规则
1.1.3、class中的成员函数与成员变量是分开存放的。即每个对象有独立的成员变量,但所有对象共享类中的成员函数。
/******************* 对象内存布局初探 ******************/
#include <iostream>
#include <string>
using namespace std;
#pragma pack(4)
class A
{
//默认访问权限private
int i;
int j;
char c;
double d;
public:
void print()
{
cout << "i = " << i << ", "
<< "j = " << j << ", "
<< "c = " << c << ", "
<< "d = " << d << endl;
}
};
#pragma pack(4) //在结构体面前指定对齐字节数。
struct B
{
//默认访问权限public
int i;
int j;
char c;
double d;
};
/*
对于对齐原则的总结:首先先想是不是32位系统,或者64位系统, 如果想要调整内存对齐,用语句
*/
A a;
int main()
{
A a;
//class和struct在内存布局上是一样的,大小相同。
cout << "sizeof(A)" << sizeof(A) << endl;
cout << "sizeof(a)" << sizeof(a) << endl; //g++下输出20byte
cout << "sizeof(B)" << sizeof(B) << endl;
cout << endl;
a.print(); //对象未初始化,在栈上创建,值是随机的
//二者内存地址相同。
B* p = reinterpret_cast<B*>(&a);//将A这个类对象指针强制转化为结构体指针,(用在指针和指针类型之间的转换或者整数和指针期间。)
//利用结构体指针对类的private成员进行赋值(注意是private成员),说明class在运行时,private访问权限只在编译期起作用。
p->i = 100;
p->j = 200;
p->c = 'C';
p->d = 3.14;
a.print(); //class中的private成员被改变。
cout << endl;
return 0;
}
1.2、运行时的对象退化为结构体的形式
1.2.1、所有成员变量在内存中依次排布
1.2.2、成员变量间可能存在内存空隙
1.2.3、可以通过内存地址直接访问成员变量
1.2.4、访问权限关键字在运行时失效
2、C++对象模型
2.1、类中的成员函数位于代码段中2.2.、调用成员函数时对象地址作为参数隐式传递(this关键字,对象的地址)
2.3、成员函数通过对象地址访问成员变量
2.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(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语言实现面向对象
#ifndef _50_2_H_
#define _50_2_H_
//为什么是void,直接指针类型(结构体指针类型)不行吗?
typedef void Demo; //进行了隐藏,和private的联系 仔细体会,模拟private,防止外界通过指针访问结构体里面的变量。 分离
//声明成员函数(接口),,每当调用这些成员函数时候,总有对象地址传递过程
Demo* Demo_Create(int i, int j);//类似构造函数
int Demo_GetI(Demo* pThis);
int Demo_GetJ(Demo* pThis); //Demo 是typedef void Demo类型
int Demo_Add(Demo* pThis, int value);
void Demo_Free(Demo* pThis);
#endif
#include "50-2.h"
#include <malloc.h>
#include <stdio.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));
if(ret != NULL)
{
ret -> mi = i;
ret -> mj = j;
}
else
{
printf("ERROR\n");
}
return ret; //将Demo改变为结构体类型,看看能否访问
}
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);
}
#include <stdio.h>
#include "50-2.h"
int main()
{
//Demo是void类型的,typedef void Demo;
Demo* d = Demo_Create(1, 2); // 构造函数, Demo* d = new Demo(1, 2);
//各函数调用中,传入this指针:d 。C++中
printf("d.mi = %d\n", Demo_GetI(d)); //d->getI(); //d具体的类指针
printf("d.mj = %d\n", Demo_GetJ(d)); //d->getJ()
printf("Add(3) = %d\n", Demo_Add(d, 3)); //d->Add(3)
//d->mi = 100; //这个d只是void类型,mi相当于私有变量,不能直接通过this指针d来访问。
Demo_Free(d);
return 0;
}
3、
小结
3.1、C++中的类对象在内存布局上与结构体相同3.2、成员变量和成员函数在内存中分开存放
3.3、访问权限关键字在运行时失效
3.4、调用成员函数时对象地址作为参数隐式传递
总结:注意因为要模拟数据私有性private,所以函数的参数应该用void,在函数内再具体操作数据。防止外界直接访问。
相关文章推荐
- 第50课 - C++ 对象模型分析(上)
- 第50课-C++对象模型分析(上)
- C++ - 多重继承和虚拟继承对象模型、效率分析
- 第51课 C++对象模型分析(下)
- C++ 多重继承和虚拟继承对象模型、效率分析
- C++多重继承和虚拟继承对象模型、效率分析
- C++对象模型和虚函数表分析以及重载、重写、隐藏的区别
- 【C++】菱形虚拟继承对象模型分析
- C++多重继承和虚拟继承对象模型、效率分析
- C++多重继承和虚拟继承对象模型、效率分析
- 29、不一样的C++系列--对象模型分析
- c++对象内存模型分析工具
- Microsoft Visual C++虚拟多继承 对象模型初步分析
- 第51课-C++对象模型分析(下)
- C++对象模型中的虚拟函数分析
- c++对象模型布局分析
- C++对象模型Data语意学分析、虚继承底层实现机制
- C++对象模型分析
- C++对象模型之函数成员(2)
- C++对象模型-详述C++对象的内存布局