我们都知道面向对象的三大特性是:封装,继承,多态。我们知道C语言是面向过程的编程语言,C++是面向对象的编程语言,当然也可以用C++写面向过程的程序,C++是面向对象和面向过程的统一。
我们首先来看一段C++代码:
#include <iostream>
#include <string>
using namespace std;
class Demo
{
private:
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;
cout<<"d.getI()="<<d.getI()<<endl;
cout<<"d.getJ()="<<d.getJ()<<endl;
cout<<"d.add(3)="<<d.add(3)<<endl;
return 0;
}
这段程序并不是很难,我们来分析一下。首先我们知道C++的类中的数据成员,和成员函数是存放在内存中的不同地方的。1.成员变量本质上是数据变量,它们要么存放在栈上,要么存放在堆空间上,要么就存放在静态存储区上。2.成员函数本质上是函数,它们只可能存放在代码段上。3那么问题就来了,既然类中的成员函数和成员变量在内存中不是存放在同一片区域,那么成员函数是怎么样访问到类中的成员变量呢??小伙伴们有没有思考过这个问题呢??当然你肯定会说直接用 .操作符嘛,比如上述例子 d.getI()不就直接访问到了吗?
下面我们就来,探索一下这个里面背后的原因,用C语言来实现面向对象里面的封装特性。
#ifndef _DEMO_H_
#define _DEMO_H_
typedef void Demo; //C语言里没有private关键字,所以通过这种方式实现信息隐藏
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);//C语言中编译器不会默认为其提供析构函数,所以必须手动提供析构函数
#endif
#include "Demo.h"
#include <malloc.h>
struct ClassDemo
{
int mi;
int mj;
};
Demo* Demo_Create(int i,int j)
{
struct ClassDemo* ret=(struct ClassDemo*)malloc(sizeof(struct ClassDemo));
if(ret)
{
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->mj+ret->mi+value;
}
void Demo_Free(Demo* pThis)
{
free(pThis);
}
#include <stdio.h>
#include "Demo.h"
int main()
{
Demo* d=Demo_Create(1,2);
printf("d.mi=%d\n",Demo_GetI(d)); //等价C++中的 d.getI()
printf("d.mj=%d\n",Demo_GetJ(d)); //等价C++中的 d.getJ()
printf("d.Add(3)=%d\n",Demo_Add(d,3)); //等价C++中的 d.add(int value)
Demo_Free(d);
return 0;
}