这里我想主要介绍下在C语言中是如何实现的面向对象。知道了C语言实现面向对象的方式,我们再联想下,C 中的class的运行原理是什么?
首先我们来写一段C 的class,拿一个Student类来举例子:
在头文件中,我定义一个Student类:
#pragma once class Student { public: void SetNumber(int number); void SetGrade(int grade); void Print(); private: int number; int grade; };
再在源文件中实现它:
#include "studentpp.h" #include
接下来是使用Student类:
#include
我们再运行一下,运行结果不出所料。
那你有没有想过,它的底层是怎么实现的?为什么不同对象,设置了不同的number和grade,它的输出却不一样?
这个问题我们先放在这。等我用C语言实现一套这种方案后,估计你就明白了。
首先,在头文件中定义一个C语言的结构体Student:
#pragma once typedef struct Student Student; Student* CreateStudent(); void DestroyStudent(Student* student); void SetNumber(Student* student, int number); void SetGrade(Student* student, int grade); void Print(Student* student);
注意在这里我使用了一个typedef,即Student = struct Student;
但是我却没有在头文件中定义它:
struct Student { int number; int grade; };
我把它放在了源文件中,在源文件中定义它,再实现相关的方法。
#include "student.h" #include
然后使用它:
#include "student.h" int main() { Student* stu1 = CreateStudent(); Student* stu2 = CreateStudent(); SetNumber(stu1, 11); SetNumber(stu2, 22); SetGrade(stu1, 111); SetGrade(stu2, 222); Print(stu1); Print(stu2); DestroyStudent(stu1); DestroyStudent(stu2); }
这是不是面向对象的原理?数据封装到了不同的指针下,不同的指针传到了相同的函数中,行为也会不同。
这时候我们再联想一下C 中的面向对象是不也是这个原理:
平时我们使用的:
a->Print();
其实它的原理可能是这样的:
void Print(Student* this) { this->number; this->grade; }
只不过编译器把默认的这个this参数隐藏在内部,我们看不见而已。其实每个成员函数默认都会有一个参数,就是对象的指针,也就是this指针。到这里你应该也就明白面向对象的原理了吧。
注意在这里我使用了一个typedef,即Student = struct Student;
但是我却没有在头文件中定义它。
这样可以更好的隐藏Student的实现,外面不知道Student究竟是什么东西,只有内部知道。在头文件中对外只暴露Student的指针,然后指针传到源文件中,再去解析它。
比如,我在其它地方想要得到Student的大小,编译器会报错,没法使用sizeof,因为它不知道Student,它只知道它是不完整的类型。而只能在源文件中使用sizeof。
这种设计是不是比C 的class更安全一些,确实安全,其实C 也可以这样实现,就是可以使用pImpl指针。
pimpl我暂时先不介绍,大家可以自己研究一下(其实历史文章中介绍过)。
大家可以思考下,怎么用C语言实现多态呢?
暂无评论