这里主要介绍如何用C语言实现面向对象。知道了C语言的面向对象方式,我们再想一想,C++中类的运行原理是什么?首先我们来写一个C??++类,以一个Student类为例:在头文件中,我定义了一个Student类:#pragmaonceclassStudent{public:voidSetNumber(intnumber);voidSetGrade(整数等级);voidPrint();private:intnumber;积分等级;};在源文件中实现:#include"studentpp.h"#includevoidStudent::SetNumber(intnumber){this->number=number;}voidStudent::SetGrade(intgrade){this->grade=grade;}voidStudent::Print(){printf("studentppnumber:%d,grade:%d\n",this->number,this->grade);}接下来是使用Student类:#include#include"studentpp.h"intmain(){Student*stu1=newStudent;学生*stu2=新学生;stu1->stu2->SetNumber(22);stu1->SetGrade(111);stu2->SetGrade(222);stu1->打印();stu2->打印();删除stu1;deletestu2;}我们再运行一??下,结果和预期的一样。有没有想过底层是怎么实现的?为什么不同的对象设置了不同的编号和等级,输出却不同?这个问题先放在这里。我用C语言实现了一套这样的方案,估计你就明白了。首先在头文件中定义一个C语言结构体Student:#pragmaoncetypedefstructStudentStudent;Student*CreateStudent();voidDestroyStudent(Student*student);voidSetNumber(Student*student,intnumber);voidSetGrade(Student*学生,年级);无效打印(学生*学生);请注意,我在这里使用了typedef,即Student=structStudent;但是我没有在头文件中定义它:structStudent{intnumber;积分等级;};我是放在源文件中,在源文件中定义,然后实现相关的方法。#include"student.h"#include#includestructStudent{intnumber;intgrade;};Student*CreateStudent(){Student*self=(Student*)malloc(sizeof(Student));returnself;}voidDestroyStudent(Student*student){if(!student)返回;free((void*)student);}voidSetNumber(Student*student,intnumber){if(!student)return;student->number=number;}voidSetGrade(Student*student,intgrade){if(!student)返回;student->grade=grade;}voidPrint(Student*student){if(!student)返回;printf("studentnumber:%d,grade:%d\n",student->number,student->grade);}然后使用它:#include"student.h"intmain(){Student*stu1=CreateStudent();学生*stu2=CreateStudent();SetNumber(stu1,11);SetNumber(stu2,22);SetGrade(stu1,111);SetGrade(stu2,222);打印(stu1);打印(stu2);(stu1);DestroyStudent(stu2);}这就是面向对象的原理吗?数据被封装在不同的指针下,不同的指针传递给同一个函数,行为会有所不同。这时候我们想想C++中的面向对象是不是也是这个道理:通常我们使用:a->Print();其实它的原理可能是这样的:voidPrint(Student*this){this->number;this->grade;}只是编译器把默认的this参数隐藏在里面了,我们看不到。其实每个成员函数默认都会有一个参数,就是对象的指针,也就是this指针。至此,你应该明白面向对象的原理了。请注意,我在这里使用了typedef,Student=structStudent;但是我没有在头文件中定义它。这样可以更好的隐藏Student的实现。外面不知道学生是什么,只有里面知道。在头文件中,对外只暴露了Student的指针,然后将指针传递给源文件,再进行解析。比如我在其他地方要获取Student的大小,编译器会报错,不能使用sizeof,因为它不知道Student,它只知道是一个不完整的类型。相反,sizeof只能在源文件中使用。这种设计比C++类更安全吗?确实安全。其实C++也可以这样实现,即可以使用pImpl指针。