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:1
Student 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:1
Student Score: 99
请按任意键继续. . .

04. 总结

C语言可以实现部分继承功能。实现对象的继承利用的是C语言编译后的内存布局。这种继承方式可以实现将扩展对象的句柄传递给基本对象。由于内存布局的特点,C语言基于对象的编程无法无法实现多重继承。

由于程序中需要隐藏细节,这种继承只能在下层的程序中定义,而很难从在调用程序中扩展。因此这种C语言所实现的知识基于对象的编程,而不能实现完全的面向对象编程。

总之,使用C语言进行基于对象编程的继承特性的时候,更多的是在下层提供的接口中,提供多个句柄表示有继承关系的对象,被继承者的处理函数可以处理继承者的句柄。

05. 附录

代码下载:C语言实现对象编程之继承代码.rar

【C语言】C语言实现面向对象编程之继承相关推荐

  1. C语言--面向对象编程之继承

    系列文章目录 C语言实现面向对象编程的第二篇,在第一篇里面我们已经了解到了何为面向对象以及实现面向对象的第一大特性–封装,对于C来说,实现继承和多态要稍微麻烦一些. C语言实现面向对象- - 封装 C ...

  2. python面向对象编程指南 脚本之家_Python面向对象编程之继承与多态详解

    本文实例讲述了Python面向对象编程之继承与多态.分享给大家供大家参考,具体如下: Python 类的继承 在OOP(Object Oriented Programming)程序设计中,当我们定义一 ...

  3. 面向对象编程之继承、多态、封装、抽象类、接口、包-上

    面向对象编程之继承.多态.封装.抽象类.接口.包-上 继承 类的继承格式 为什么要继承 继承的特点 继承的种类及关键字 访问权限 多态 向上转型 动态绑定 方法重写 重写和重载的区别比较 多态的优点 ...

  4. 7、JS面向对象编程之继承

    Javascript本身是从Perl语言的语法演变而来的,本质上是脚本语言,随着版本的更新逐渐加入的对面向对象的模拟.我认为Js的面向对象模拟总体上做得还是不错的,因为我们不能盲从任何一种理念,不能纯 ...

  5. js原生设计模式——2面向对象编程之继承—new+call(this)组合式继承

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  6. Java面向对象编程之继承练习题(三)

    作业1 写一个Person类,有编号id,姓名name,职位job. 构造方法带三个参数. 方法: 登陆login 注册register 自我介绍talk 写一个学生Student类继承Person类 ...

  7. C语言--面向对象编程之多态

    系列文章目录 C语言–面向对象编程之封装 C语言–面向对象编程之继承 文章目录 系列文章目录 前言 一.多态是什么? 二.C语言实现多态 1.多态基本实现原理 2.一个简单的demo 3.简要分析 三 ...

  8. C/C++面向对象编程之多态

    C/C++面向对象编程 目录: 1.类型转换 2.为什么引入多态和虚函数 3.编译器如何实现多态和虚函数 4.多态的思想 5.C语言用实现多态的思想 目录: C/C++面向对象编程之封装 C/C++面 ...

  9. 【C语言】C语言实现面向对象编程之封装

    00. 目录 文章目录 00. 目录 01. 前言 02. 简单程序示例 03. 程序示例优化 04. 总结 05. 参考 01. 前言 面向对象编程(OOP)并不是一种特定的语言或者工具,它只是一种 ...

最新文章

  1. postgis学习笔记
  2. Python最热,PyTorch增速是TF的13倍:2019数据分析/机器学习工具调查发布
  3. SSH框架的简单搭建步骤
  4. java中的alert是什么意思_javascript 中如何使用alert?
  5. Mysql安装和常用命令及问题汇总
  6. python七夕快乐图片_提前祝七夕快乐图片
  7. c语言字符常量和字符串常量_C语言中的字符常量
  8. oracle19c 安装权限_Oracle19c 安装及SQL developer连接
  9. java jar命令_Java命令行之jar命令
  10. Matlab论文插图绘制模板第19期—散点折线图
  11. 关于Hsql无法插入的问题
  12. 数字孪生北京故宫,元宇宙推进旅游业进程
  13. 算法-“许三多”方法
  14. 关于错误“未能加载文件或程序集”的错误的若干处理办法——对GAC的简单应用
  15. SAP中采购合同与采购计划协议关联性分析(续)
  16. android课程设计体重测量仪,智能体重检测仪设计与实现
  17. 引用bootstrap的两种方法
  18. web图片裁切插件 cropper.js 详细介绍
  19. 启英泰伦cl1122模块学习笔记
  20. cs231n:assignment2——Q1: Fully-connected Neural Network

热门文章

  1. input border IE6 bug
  2. C#使用BackgroundWorker实现多线程
  3. 手机应用在线打包url
  4. ZOJ POJ题目分类
  5. struts2 s:optiontransferselect 标签的使用
  6. 未处理的异常:进程性能计数器已禁用
  7. 7-4 找到共同的选修课-hebust (10 分)
  8. C语言程序练习-L1-030 一帮一 (15分)
  9. 每日程序C语言28-有序数组插入元素
  10. id3决策树 鸢尾花 python_C4.5决策树Python代码实现