没有合适的资源?快使用搜索试试~ 我知道了~
首页轻量级的面向对象(LW_OOPC)
资源详情
资源评论
资源推荐
轻量级的面向对象 C 语言编程框架 LW_OOPC 介绍
金永华、陈国栋
2010/03/02
摘要:
本文介绍一种轻量级的面向对象的 C 语言编程框架:LW_OOPC。LW_OOPC 是 Light-
Weight Object-Oriented Programming in(with) C 的缩写,总共一个.h 文件,20 个宏,约 130
行代码,非常的轻量级,但却很好的支持了很多面向对象的特性,比如继承、多态,可以
优美的实现面向接口编程。这个框架系由台湾的高焕堂先生以及他的 MISOO 团队首创,
之后由我继续改进优化,最后,经高焕堂同意以 LGPL 协议开源(开源网址参见后文)。
用 C 语言实现 OO?我没听错吗?这听起来真是太疯狂了!… 大家都知道,C++支持
了面向对象和面向泛型编程,比 C 要更强大些。那么,为什么要在 C 语言中实践面向对象
呢?为什么不直接使用 C++呢?
为什么要用面向对象?
面向过程方式开发的系统,代码复杂,耦合性强,难以维护,随着我们所要解决的问
题越来越复杂,代码也变得越来越复杂,越来越难以掌控,而面向对象改变了程序员的思
维方式,以更加符合客观世界的方式来认识世界,通过合理的运用抽象、封装、继承和多
态,更好的组织程序,从而很好地应对这种复杂性。
为什么不直接使用 C++?
C 和 C++之争由来已久,可能要持续到它们中的一种去世^_^。C 语言以其简洁明快,
功能强大的特点,深得开发人员的喜爱,尤其是在嵌入式开发领域, C 语言更是占据了绝
对老大的地位。在我看来,语言只是工具,作为程序员,我们要做的是:选择合适的语言
解决恰当的问题。我们要尊重事实,考虑开发环境(软硬件环境),考虑团队成员的水平
从商用工程的角度讲,选择团队成员擅长的语言进行开发,风险要小很多。
一些从 Java/C#转到 C 的程序员们,无法从面向对象切换到面向过程,但又必须与 C 语
言同事们在遗留的 C 系统上开发软件,他们有时会非常困惑:C 语言是面向过程的编程语
言,如何实践面向对象,甚至面向接口编程呢?此时,就非常需要在 C 语言中实现面向对
象的手段,而 LW_OOPC 正是应对这一难题的解决之道。
LW_OOPC 是什么?
简而言之:LW_OOPC 是一套 C 语言的宏,总共 1 个.h 文件(如果需要内存泄漏检测
支持以及调试打印支持,那么还需要 1 个.c 文件(lw_oopc.c,约 145 行)),20 个宏,约
130 行代码。LW_OOPC 是一种 C 语言编程框架,用于支持在 C 语言中进行面向对象编程。
LW_OOPC 宏介绍
下面,先通过一个简单的示例来展示 LW_OOPC 这套宏的使用方法。我们要创建这样
一些对象:动物(Animal),鱼( Fish),狗( Dog),车子( Car)。显然,鱼和狗都
属于动物,都会动,车子也会动,但是车子不是动物。会动是这些对象的共同特征,但是
显然它们不属于一个家族。因此,我们首先考虑抽象出一个接口(IMoveable),以描述会
动这一行为特征:
INTERFACE(IMoveable)
{
void (*move)(IMoveable* t); // Move行为
};
INTERFACE 宏用于定义接口,其成员(方法)均是函数指针类型。
然后,我们分析 Animal,它应该是抽象类还是接口呢?动物都会吃,都需要呼吸,如
果仅仅考虑这两个特征,显然可以把 Animal 定为接口。不过,这里,为了展示抽象类在
LW_OOPC 中如何应用。我们让 Animal 拥有昵称和年龄属性,并且,让动物和我们打招呼
(sayHello 方法),但,我们不允许用户直接创建 Animal 对象,所以,这里把 Animal 定为
抽象类:
ABS_CLASS(Animal)
{
char name[128]; // 动物的昵称(假设小于128个字符)
int age; // 动物的年龄
void (*setName)(Animal* t, const char* name); // 设置动物的昵称
void (*setAge)(Animal* t, int age); // 设置动物的年龄
void (*sayHello)(Animal* t); // 动物打招呼
void (*eat)(Animal* t); // 动物都会吃(抽象方法,由子
类实现)
void (*breathe)(Animal* t); // 动物都会呼吸(抽象方法,由子
类实现)
void (*init)(Animal* t, const char* name, int age); // 初始化昵称和年
龄
};
ABS_CLASS 宏用于定义抽象类,允许有成员属性。代码的含义参见代码注释。
紧接着,我们来定义 Fish 和 Dog 类,它们都继承动物,然后还实现了 IMoveable 接口:
CLASS(Fish)
{
EXTENDS(Animal); // 继承Animal抽象类
IMPLEMENTS(IMoveable); // 实现IMoveable接口
void (*init)(Fish* t, const char* name, int age); // 初始化昵称和年龄
};
CLASS(Dog)
{
EXTENDS(Animal); // 继承Animal抽象类
IMPLEMENTS(IMoveable); // 实现IMoveable接口
void(*init)(Dog* t, const char* name, int age); // 初始化昵称和年龄
};
为了让 Fish 对象或 Dog 对象在创建之后,能够很方便地初始化昵称和年龄,Fish 和
Dog 类均提供了 init 方法。
下面,我们来定义 Car,车子不是动物,但可以 Move,因此,让 Car 实现 IMoveable
接口即可:
CLASS(Car)
{
IMPLEMENTS(IMoveable); // 实现IMoveable接口(车子不是动物,但可以Move)
};
接口,抽象类,具体类的定义都已经完成了。下面,我们开始实现它们。接口是不需
要实现的,所以 IMoveable 没有对应的实现代码。Animal 是抽象动物接口,是半成品,所
以需要提供半成品的实现:
/* 设置动物的昵称*/
void Animal_setName(Animal* t, const char* name)
{
// 这里假定name不会超过128个字符,为简化示例代码,不做保护(产品代码中不要这样写)
strcpy(t->name, name);
}
/* 设置动物的年龄*/
void Animal_setAge(Animal* t, int age)
{
t->age = age;
}
/* 动物和我们打招呼*/
void Animal_sayHello(Animal* t)
{
printf("Hello! 我是%s,今年%d岁了!\n", t->name, t->age);
}
/* 初始化动物的昵称和年龄*/
void Animal_init(Animal* t, const char* name, int age)
{
t->setName(t, name);
t->setAge(t, age);
}
ABS_CTOR(Animal)
FUNCTION_SETTING(setName, Animal_setName);
FUNCTION_SETTING(setAge, Animal_setAge);
FUNCTION_SETTING(sayHello, Animal_sayHello);
FUNCTION_SETTING(init, Animal_init);
END_ABS_CTOR
这里出现了几个新的宏,我们逐个进行讲解。ABS_CTOR 表示抽象类的定义开始,
ABS_CTOR(Animal)的含义是 Animal 抽象类的“构造函数”开始。在 C 语言里边其实是没有
C++ 中 的 构 造 函 数 的 概 念 的 。 LW_OOPC 中 的 CTOR 系 列 宏 ( CTOR/
END_CTOR,ABS_CTOR/END_ABS_CTOR)除了给对象(在 C 语言中是 struct 实例)分
配内存,然后,紧接着要为结构体中的函数指针成员赋值,这一过程,也可以称为函数绑
定(有点类似 C++中的动态联编)。函数绑定的过程由 FUNCTION_SETTING 宏来完成。
对于 Fish 和 Dog 类的实现,与 Animal 基本上是类似的,除了将 ABS_CTOR 换成了
CTOR,直接参见代码:
/* 鱼的吃行为 */
void Fish_eat(Animal* t)
{
printf("鱼吃水草!\n");
}
/* 鱼的呼吸行为 */
void Fish_breathe(Animal* t)
{
printf("鱼用鳃呼吸!\n");
}
/* 鱼的移动行为 */
void Fish_move(IMoveable* t)
{
printf("鱼在水里游!\n");
}
/* 初始化鱼的昵称和年龄 */
void Fish_init(Fish* t, const char* name, int age)
{
Animal* animal = SUPER_PTR(t, Animal);
animal->setName(animal, name);
animal->setAge(animal, age);
}
CTOR(Fish)
SUPER_CTOR(Animal);
FUNCTION_SETTING(Animal.eat, Fish_eat);
FUNCTION_SETTING(Animal.breathe, Fish_breathe);
FUNCTION_SETTING(IMoveable.move, Fish_move);
FUNCTION_SETTING(init, Fish_init);
END_CTOR
上面是 Fish 的实现,下面看 Dog 的实现:
/* 狗的吃行为 */
void Dog_eat(Animal* t)
{
printf("狗吃骨头!\n");
}
/* 狗的呼吸行为 */
void Dog_breathe(Animal* t)
{
printf("狗用肺呼吸!\n");
}
/* 狗的移动行为 */
void Dog_move(IMoveable* t)
{
剩余16页未读,继续阅读
luyysea
- 粉丝: 16
- 资源: 11
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- 数据结构1800题含完整答案详解.doc
- 医疗企业薪酬系统设计与管理方案.pptx
- 界面与表面技术界面理论与表面技术要点PPT学习教案.pptx
- Java集合排序及java集合类详解(Collection、List、Map、Set)讲解.pdf
- 网页浏览器的开发 (2).pdf
- 路由器原理与设计讲稿6-交换网络.pptx
- 火电厂锅炉过热汽温控制系统设计.doc
- 企业识别CIS系统手册[收集].pdf
- 物业管理基础知识.pptx
- 第4章财务预测.pptx
- 《集成电路工艺设计及器件特性分析》——实验教学计算机仿真系.pptx
- 局域网内共享文件提示没有访问权限的问题借鉴.pdf
- 第5章网络营销策略.pptx
- 固井质量测井原理PPT教案.pptx
- 毕业实习总结6篇.doc
- UGNX建模基础篇草图模块PPT学习教案.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0