00. 目录
文章目录
00. 目录01. 概述02. 利用结构体包含实现继承功能03. 利用私有指针实现继承功能04. 总结05. 附录01. 概述
面向对象编程具有封装性、继承性、多态性三个基本特性。使用C语言可以实现基于对象的编程。在基于对象编程实现封装的基础之上,我们接下来实现面向对象编程中的继承部分功能。这种继承特性知识实现部分面向对象编程中继承功能。本博客中我们介绍两种方式的实现继承。第一种是利用数据结构的包含实现继承功能,第二种是利用私有指针实现继承功能,它们提供的接口是完全一致的,只是在实现方式上略有不同。
02. 利用结构体包含实现继承功能
在C语言的基于对象编程方面,可以利用结构体包含的扩展实现一定的继承性。下面实现定义一个Student结构,它实现了对Person结构的扩展。
接口文件test.h声明如下
#ifndef __TEST_H__#define __TEST_H__#ifdef __cplusplus//表示是C语言的头文件extern "C"{#endiftypedef void * HPERSON;//创建对象HPERSON createPerson(const char *name);//设置对象void setPerson(HPERSON person, int age, int id);//显示对象void displayPerson(HPERSON person);//删除对象void deletePerson(HPERSON person);#ifdef __cplusplus}#endif//-----------------STUDENT-----------------typedef void* HSTUDENT;//创建对象HSTUDENT createStudent(const char *name);//设置对象void setStudent(HSTUDENT student, int age, int id, int score);//显示对象void displayStudent(HSTUDENT student);//删除对象void deleteStudent(HSTUDENT student);#endif /*__TEST_H__*/
实现文件test.c如下
#define _CRT_SECURE_NO_WARNINGS#include "test.h"#include <stdio.h>#include <stdlib.h>#include <string.h>//Person表示HPERSON句柄指向的结构体typedef struct _Person {//使用指针char *name;int age;int id;}Person;//创建对象HPERSON createPerson(const char * name){Person *p = NULL;printf("创建对象\n");p = malloc(sizeof(Person));if (NULL == p){printf("分配内存失败\n");return NULL;}memset(p, 0, sizeof(Person));p->name = malloc(strlen(name) + 1);if (NULL == p->name){printf("分配内存失败\n");return NULL;}strcpy(p->name, name);p->age = 0;p->id = 0;return p;}//设置对象void setPerson(HPERSON person, int age, int id){Person *p = person;if (NULL != p){p->age = age;p->id = id;}}//显示对象void displayPerson(HPERSON person){Person *p = person;if (NULL == p){printf("displayPerson 参数非法\n");return;}printf("Name: %s age: %d id:%d\n", p->name, p->age, p->id);}//删除对象void deletePerson(HPERSON person){Person *p = person;if (NULL == person){return;}if (NULL != p->name){free(p->name);}free(person);}//---------------------STUDENT--------------------typedef struct _stu_t {Person person;int score;}Student;//创建对象HSTUDENT createStudent(const char *name){Student *s = malloc(sizeof(Student));if (NULL == s){return NULL;}memset(s, 0, sizeof(Student));s->person.name = malloc(strlen(name) + 1);if (NULL == s->person.name){return;}memset(s->person.name, 0, strlen(name) + 1);strcpy(s->person.name, name);s->score = 0;return s;}//设置对象void setStudent(HSTUDENT student, int age, int id, int score){Student *s = student;if (NULL == s){return;}setPerson(&(s->person), age, id);s->score = score;}//显示对象void displayStudent(HSTUDENT student){Student *s = student;if (NULL == s){return;}displayPerson(&(s->person));printf("Student Score: %d\n", s->score);}//删除对象void deleteStudent(HSTUDENT student){Student *s = student;if (NULL == s){return;}if (NULL != s->person.name){free(s->person.name);}free(s);}
测试文件实现如下
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>#include<stdlib.h>#include "test.h"int main(){HSTUDENT s = createStudent("李明");setStudent(s, 12, 1, 99);displayStudent(s);deleteStudent(s);system("pause");return 0;}
测试结果
Name: 李明 age: 12 id:1Student Score: 99请按任意键继续. . .
03. 利用私有指针实现继承功能
在C语言基于对象编程的继承问题上,通常还可以利用私有的指针实现继承。
test.h声明如下
#ifndef __TEST_H__#define __TEST_H__#ifdef __cplusplus//表示是C语言的头文件extern "C"{#endiftypedef void * HPERSON;//创建对象HPERSON createPerson(const char *name);//设置对象void setPerson(HPERSON person, int age, int id);//显示对象void displayPerson(HPERSON person);//删除对象void deletePerson(HPERSON person);#ifdef __cplusplus}#endif//-----------------STUDENT-----------------typedef void* HSTUDENT;//创建对象HSTUDENT createStudent(const char *name);//设置对象void setStudent(HSTUDENT student, int age, int id, int score);//显示对象void displayStudent(HSTUDENT student);//删除对象void deleteStudent(HSTUDENT student);#endif /*__TEST_H__*/
test.c实现如下
#define _CRT_SECURE_NO_WARNINGS#include "test.h"#include <stdio.h>#include <stdlib.h>#include <string.h>//Person表示HPERSON句柄指向的结构体typedef struct _Person {//使用指针char *name;int age;int id;void *priv;}Person;//创建对象HPERSON createPerson(const char * name){Person *p = NULL;printf("创建对象\n");p = malloc(sizeof(Person));if (NULL == p){printf("分配内存失败\n");return NULL;}memset(p, 0, sizeof(Person));p->name = malloc(strlen(name) + 1);if (NULL == p->name){printf("分配内存失败\n");return NULL;}strcpy(p->name, name);p->age = 0;p->id = 0;//私有数据初始化p->priv = NULL;return p;}//设置对象void setPerson(HPERSON person, int age, int id){Person *p = person;if (NULL != p){p->age = age;p->id = id;}}//显示对象void displayPerson(HPERSON person){Person *p = person;if (NULL == p){printf("displayPerson 参数非法\n");return;}printf("Name: %s age: %d id:%d\n", p->name, p->age, p->id);}//删除对象void deletePerson(HPERSON person){Person *p = person;if (NULL == person){return;}if (NULL != p->name){free(p->name);}free(person);}//---------------------STUDENT--------------------typedef struct _stu_t {int score;}StudentPriv;//创建对象HSTUDENT createStudent(const char *name){Person *p = NULL;p = malloc(sizeof(Person));if (NULL == p){printf("分配内存失败\n");return NULL;}memset(p, 0, sizeof(Person));p->name = malloc(strlen(name) + 1);if (NULL == p->name){printf("分配内存失败\n");return NULL;}strcpy(p->name, name);p->age = 0;p->id = 0;//创建Student的私有数据p->priv = malloc(sizeof(StudentPriv));if (NULL == p->priv){printf("分配内存失败\n");return NULL;}((StudentPriv*)p->priv)->score = 0;return p;}//设置对象void setStudent(HSTUDENT student, int age, int id, int score){Person *s = student;if (NULL == s){return;}setPerson(s, age, id);((StudentPriv*)s->priv)->score = score;}//显示对象void displayStudent(HSTUDENT student){Person *s = student;if (NULL == s){return;}displayPerson(s);printf("Student Score: %d\n", ((StudentPriv*)s->priv)->score);}//删除对象void deleteStudent(HSTUDENT student){Person *s = student;if (NULL == s){return;}if (NULL != s->name){free(s->name);}free(s);}
测试程序main.c实现如下
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>#include<stdlib.h>#include "test.h"int main(){HSTUDENT s = createStudent("李明");setStudent(s, 12, 1, 99);displayStudent(s);deleteStudent(s);system("pause");return 0;}
测试结果
Name: 李明 age: 12 id:1Student Score: 99请按任意键继续. . .
04. 总结
C语言可以实现部分继承功能。实现对象的继承利用的是C语言编译后的内存布局。这种继承方式可以实现将扩展对象的句柄传递给基本对象。由于内存布局的特点,C语言基于对象的编程无法无法实现多重继承。
由于程序中需要隐藏细节,这种继承只能在下层的程序中定义,而很难从在调用程序中扩展。因此这种C语言所实现的知识基于对象的编程,而不能实现完全的面向对象编程。
总之,使用C语言进行基于对象编程的继承特性的时候,更多的是在下层提供的接口中,提供多个句柄表示有继承关系的对象,被继承者的处理函数可以处理继承者的句柄。
05. 附录
代码下载:C语言实现对象编程之继承代码.rar