当前位置: 首页 > 科技观察

C语言如何实现面向对象

时间:2023-03-16 16:20:57 科技观察

这里主要介绍C语言如何实现面向对象。知道了C语言的面向对象方式,我们来想一想,C++中类的运行原理是什么?先来看一个C++类,以一个Student类为例:在头文件中,我定义了一个Student类:#pragmaonceclassStudent{public:voidSetNumber(intnumber);voidSetGrade(整数等级);voidPrint();private:整数;积分等级;};在源文件中实现:#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->SetNumber(11);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指针。pimpl我暂时不介绍了,大家可以自己研究下(其实在历史文章里有介绍)。大家可以想一想,怎么用C语言来实现多态呢?