有人认为面向对象是C++/Java这种高级语言的专利,实际不是这样,面向对象作为一种设计方法,是不限制语言的。只能说,用C++/Java这种语法来实现面向对象会更容易、更自然一些。
在本节中,就展示如何在C语言中实现面向对象编程,这是一件吃力的工作。写这些的目的有两个:
① 更好的掌握C++中的class的概念。学习了本章,就知道C程序员的无耐,就知道为什么要发明一个class的概念、为什么要有成员函数等等。
② 为C程序员提供一个参考设计。由在存在某些场合,只允许用C语言来编程,不允许用C++来编程。这时候,可以参考本篇的代码,用C的语法来模拟C++的类来实现面向对象编程。
本篇按从易到难的顺序,提供几种基于C struct的面向对象的写法。在本节的展示中,统一以.c后缀命名文件,也就是说,是以C语言的语法来书写代码。C语言和C++的struct写法略有区别,请参考附录《C++与C的区别》。
权利声明:作者拥有本书的全部权利。作者授权任何人都可以自由转载本网站发布的内容,但转载时必须遵守以下限制: ①转载时必须全文转载,不得有任何修改,必须包含“权利声明”和“官网地址” ② 仅限于网络转载,即最终结果公布于网络上。凡是不遵守以上两条的转载行为视为侵权行为。除非本人允许,任何人不得将本网站内容内容用于任何的其他用途。
官网地址: http://www.afanihao.cn/ 留言请到http://www.afanihao.cn/kbase/
1.1 第1种方法
这种方法只适合单一实例的对象。以打印机Print对象为例,系统中只存在一台打印机,此时按以下方法提供接口,
首先,给出printer.h,里面写明对外的接口,
/////////////////// printer.h begin ///////////////
#ifndef _PRINTER_H
#define _PRINTER_H
int pr_open(); // 打开打印机
void pr_close(); // 关闭打印机
void pr_print(const char* text); // 打印文本
#endif
/////////////////////////////////////////////////////
其次,给出printer.c,给出函数接口的实现。由于没有办法操纵一台真实的打印机,那样代码太复杂,作者不容易理解。所以这里使用“虚拟打印机”的概念,所谓“打印”,只是将文件写到指定的文件c:\printer.txt里,
/////////////////// printer.c ///////////////
#include <stdio.h>
#include "printer.h"
// 定义
typedef struct
{
FILE* outfile;
}printer_t;
// 定义唯一实例
static printer_t pr = { NULL };
// 打开打印机
int pr_open()
{
pr.outfile = fopen("c:/printer.txt", "ab");
if(pr.outfile == NULL)
return -1;
return 0;
}
// 关闭打印机
void pr_close()
{
if(pr.outfile)
{
fclose(pr.outfile);
pr.outfile = NULL;
}
}
// 打印文本
void pr_print(const char* text)
{
fprintf(pr.outfile, text);
}
/////////////////// ///////////////
在main.c中这么调用
/////////////////// main.c ///////////////
#include "printer.h"
void main()
{
pr_open(); // 打开
pr_print("aaabbbccc\n"); // 输出文本
pr_close(); // 关闭
}
可以总结出这种写法的特点:
(1) 虽然是面向对象,但只有一个对象,该对象外部不可见;
(2) 外界只能通过函数接口该对象的功能。可以发现,函数中并没有传入对象的指针。
1.2 第2种方法
当可以创建多个对象时,使用此种方法来实现。仍然前面的printer为例,其实这个printer只是一个“虚拟”的打印机,最终目标是输出到一个本地的文件。那么,可以允许创建多个printer对象的。
头文件printer.h中定义对象,在提供的接口函数都有对象指针,其中~open函数用于创建一个对象,~close用于销毁对象,
///////////////////printer.h ///////////////
#ifndef _PRINTER_H
#define _PRINTER_H
#include <stdio.h>
typedef struct
{
FILE* outfile;
}printer_t;
printer_t* pr_open(const char* filename); // 打开打印机
void pr_close(printer_t* pr); // 关闭打印机
void pr_print(printer_t* pr, const char* text); // 打印文本
#endif
下面是它的实现,
///////////////////printer.c ///////////////
#include <stdio.h>
#include <stdlib.h>
#include "printer.h"
// 打开打印机
printer_t* pr_open(const char* filename)
{
printer_t* pr = (printer_t*)malloc(sizeof(printer_t));
pr->outfile = fopen(filename, "ab");
if(!pr->outfile)
{
free(pr);
return NULL;
}
return pr;
}
// 关闭打印机
void pr_close(printer_t* pr)
{
fclose(pr->outfile);
free(pr);
}
// 打印文本
void pr_print(printer_t* pr, const char* text)
{
fprintf(pr->outfile, text);
}
在main.c的调用这个对象,
///////////////////main.c ///////////////
#include "printer.h"
void main()
{
printer_t* pr = pr_open("c:/1.txt");
pr_print(pr, "aaabbbccc\n");
pr_close(pr);
}
至此,面向对象已经比较完整,它有3个要素:
① 对象的创建:使用pr_open函数来创建一个对象,允许创建多个对象;
② 对象的销毁: 使用pr_close来销毁对象
③ 对象的功能接口: pr_print是其功能接口,注意这个函数的第一个参数就是指向了一个对象
1.3 第3种方法
这种方法是对方法2的升级,理念和方法2一样。它是在形式上和C++的class基本一致,或许可以说,C++的class是从这种方法演化而来的。
。。。本节内容不公开,更多内容请购买纸质教材,谢谢支持!。。。