C语言如何实现面向对象

C语言如何实现面向对象

C语言实现面向对象

#这里主要介绍下在C语言中是如何实现面向对象的。知道了C语言实现面向对象的方式,再联想一下,C++中的class的运行原理是什么?

C++中的class示例

#首先看一段C++的class,拿一个Student类来举例:

头文件(studentpp.h)

##pragma once

class Student {

public:

void SetNumber(int number);

void SetGrade(int grade);

void Print();

private:

int number;

int grade;

};

源文件(studentpp.cpp)

##include "studentpp.h"

#include

void Student::SetNumber(int number) { this->number = number; }

void Student::SetGrade(int grade) { this->grade = grade; }

void Student::Print() { printf("studentpp number : %d, grade : %d \n", this->number, this->grade); }

使用Student类

##include

#include "studentpp.h"

int main() {

Student *stu1 = new Student;

Student *stu2 = new Student;

stu1->SetNumber(11);

stu2->SetNumber(22);

stu1->SetGrade(111);

stu2->SetGrade(222);

stu1->Print();

stu2->Print();

delete stu1;

delete stu2;

}

运行结果不出所料。有没有想过,它的底层是怎么实现的?为什么不同对象,设置了不同的number和grade,它的输出却不一样?

这个问题先放在这。等我用C语言实现一套这种方案后,估计就明白了。

C语言实现面向对象

#头文件(student.h)

##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;

};

我把它放在了源文件中,在源文件中定义它,再实现相关的方法。

源文件(student.c)

##include "student.h"

#include

#include

struct Student {

int number;

int grade;

};

Student* CreateStudent() {

Student* self = (Student*)malloc(sizeof(Student));

return self;

}

void DestroyStudent(Student* student) {

if (!student) return;

free((void*)student);

}

void SetNumber(Student* student, int number) {

if (!student) return;

student->number = number;

}

void SetGrade(Student* student, int grade) {

if (!student) return;

student->grade = grade;

}

void Print(Student* student) {

if (!student) return;

printf("student number : %d, grade : %d \n", student->number, student->grade);

}

使用C语言实现的Student

##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语言实现多态呢?

相关推荐

這些明星被爆料身上有難聞異味,臭到揚名演藝圈
ps如何画漫画?漫画画法步骤详解
史上最全的北京“黑话”!“混北京”必备!