C语言实现封装、继承和多态
来源:互联网 发布:c语言 面向过程 编辑:程序博客网 时间:2024/05/21 06:40
转载自:http://dongxicheng.org/cpp/ooc/
1、 概述
C语言是一种面向过程的程序设计语言,而C++是在C语言基础上衍生来了的面向对象的语言,实际上,很多C++实现的底层是用C语言实现的,如在Visual C++中的Interface其实就是struct,查找Interface的定义,你可以发现有这样的宏定义:
#ifndef Interface
#define Interface struct
#endif
C++在语言级别上添加了很多新机制(继承,多态等),而在C语言中,我们也可以使用这样的机制,前提是我们不得不自己实现。
本文介绍了用C语言实现封装,继承和多态的方法。
2、 基本知识
在正式介绍C语言实现封装,继承和多态事前,先介绍一下C语言中的几个概念和语法。
(1) 结构体
在C语言中,常把一个对象用结构体进行封装,这样便于对对象进行操作,比如:
strcut Point{
int
x;
int
y;
};
结构体可以嵌套。因而可以把一个结构体当成另一个结构体的成员,如:
struct
Circle {
struct
Point point_;
int
radius;
};
该结构体与以下定义完全一样(包括内存布置都一样):
struct
Circle {
int
x;
int
y;
int
radius;
};
(2) 函数指针
函数指针是指针的一种,它指向函数的首地址(函数的函数名即为函数的首地址),可以通过函数指针来调用函数。
如函数:
int func(int a[], int n);
可以这样声明函数指针:
int (*pFunc)(int a[], int n);
这样使用:
pFunc = func;
(*pFunc)(a, n);【或者PFunc(a, n)】
可以用typedef定义一个函数指针类型,如:
typdef int (*FUNC)(int a[], int n)
可以这样使用:
int cal_a(FUNC fptr, int a[], int n)
{
//实现体
}
(3) extern与static
extern和static是C语言中的两个修饰符,extern可用于修饰函数或者变量,表示该变量或者函数在其他文件中进行了定义;static也可用于修饰函数或者变量,表示该函数或者变量只能在该文件中使用。可利用它们对数据或者函数进行隐藏或者限制访问权限。
3、 封装
在C语言中,可以用结构+函数指针来模拟类的实现,而用这种结构定义的变量就是对象。
封装的主要含义是隐藏内部的行为和信息,使用者只用看到对外提供的接口和公开的信息。有两种方法实现封装:
(1) 利用C语言语法。在头文件中声明,在C文件中真正定义它。
这样可以隐藏内部信息,因为外部不知道对象所占内存的大小,所以不能静态的创建该类的对象,只能调用类提供的创建函数才能创建。这种方法的缺陷是不支持继承,因为子类中得不到任何关于父类的信息。如:
//头文件:point.h
#ifndef POINT_H
#define POINT_H
struct
Point;
typedef
struct
Point point;
point * new_point();
//newer a point object
void
free_point(point *point_);
// free the allocated space
#endif
//C文件:point.c
#include”point.h”
strcut Point
{
int
x;
int
y;
};
point * new_point()
{
point * new_point_ = (point *)
malloc
(
sizeof
(point));
return
new_point_;
}
void
free_point(point *point_)
{
if
(point_ == NULL)
return
;
free
(point_);
}
(2) 把私有数据信息放在一个不透明的priv变量或者结构体中。只有类的实现代码才知道priv或者结构体的真正定义。如:
#ifndef POINT _H
#define POINT_H
typedef
struct
Point point;
typedef
struct
pointPrivate pointPrivate;
strcut Point
{
Struct pointPrivate *pp;
};
int
get_x(point *point_);
int
get_y(point *point_);
point * new_point();
//newer a point object
void
free_point(point *point_);
// free the allocated space
#endif
//C文件:point.c
#include”point.h”
struct
pointPrivate
{
int
x;
int
y;
}
int
get_x(point *point_)
{
return
point_->pp->x;
}
int
get_y(point *point_)
{
return
point_->pp->y;
}
//others…..
4、 继承
在C语言中,可以利用“结构在内存中的布局与结构的声明具有一致的顺序”这一事实实现继承。
比如我们要设计一个作图工具,其中可能涉及到的对象有Point(点),Circle(圆),由于圆是由点组成的,所有可以看成Circle继承自Point。另外,Point和Circle都需要空间申请,空间释放等操作,所有他们有共同的基类Base。
//内存管理类new.h
#ifndef NEW_H
#define NEW_H
void
*
new
(
const
void
*
class
, ...);
void
delete
(
void
* item);
void
draw (
const
void
* self);
#endif
//内存管理类的C文件:new.c
#include “new.h”
#include “base.h”
void
*
new
(
const
void
* _base, ...)
{
const
struct
Base * base = _base;
void
* p =
calloc
(1, base->size);
assert
(p);
* (
const
struct
Base **) p = base;
if
(base ->ctor)
{
va_list
ap;
va_start
(ap, _base);
p = base ->ctor(p, &ap);
va_end
(ap);
}
return
p;
}
void
delete
(
void
* self)
{
const
struct
Base ** cp = self;
if
(self && * cp && (* cp) —> dtor)
self = (* cp) —>dtor(self);
free
(self);
}
void
draw (
const
void
* self)
{
const
struct
Base *
const
* cp = self;
assert
(self &&* cp && (* cp)->draw);
(* cp) ->draw(self);
}
//基类:base.h
#ifndef BASE_H
#define BASE_H
struct
Base
{
size_t
size;
//类所占空间
void
* (* ctor) (
void
* self,
va_list
* app);
//构造函数
void
* (* dtor) (
void
* self);
//析构函数
void
(* draw) (
const
void
* self);
//作图
};
#endif
//Point头文件(对外提供的接口):point.h
#ifndef POINT_H
#define POINT_H
extern
const
void
* Point;
/* 使用方法:new (Point, x, y); */
#endif
//Point内部头文件(外面看不到):point.r
#ifndef POINT_R
#define POINT_R
struct
Point
{
const
void
* base;
//继承,基类指针,放在第一个位置,const是防止修改
int
x, y;
//坐标
};
#endif
//Point的C文件:point.c
#include “point.h”
#include “new.h”
#include “point.h”
#include “point.r”
static
void
* Point_ctor (
void
* _self,
va_list
* app)
{
struct
Point * self = _self;
self ->x =
va_arg
(* app,
int
);
self ->y =
va_arg
(* app,
int
);
return
self;
}
static
void
Point_draw (
const
void
* _self)
{
const
struct
Point * self = _self;
printf
(“draw (%d,%d)”, self -> x, self -> y);
}
static
const
struct
Base _Point = {
sizeof
(
struct
Point), Point_ctor, 0, Point_draw
};
const
void
* Point = & _Point;
//测试程序:main.c
#include “point.h”
#include “new.h”
int
main (
int
argc,
char
** argv)
{
void
* p =
new
(Point, 1, 2);
draw(p);
delete
(p);
}
同样,Circle要继承Point,则可以这样:
struct
Circle
{
const
struct
Point point;
//放在第一位,可表继承
int
radius;
};
5、 多态
可以是用C语言中的万能指针void* 实现多态,接上面的例子:
//测试main.c
void
* p =
new
(Point, 1, 2);
void
* pp =
new
(Circle, 1, 2);
draw(p);
//draw函数实现了多态
draw(pp);
delete
(p);
delete
(pp);
6、 总结
C语言能够模拟实现面向对象语言具有的特性,包括:多态,继承,封装等,现在很多开源软件都了用C语言实现了这几个特性,包括大型开源数据库系统postgreSQL,可移植的C语言面向对象框架GObject,无线二进制运行环境BREW。采用C语言实现多态,继承,封装,能够让软件有更好的可读性,可扩展性。
7、 参考资料
(1) 《C语言中extern和static用法》:
http://www.cnblogs.com/hishope/archive/2008/08/28/1278822.html
(2) 《三、使用GObject——私有成员和静态变量》:
http://blog.csdn.net/wormsun/archive/2009/11/25/4874465.aspx
(3) 《技巧:用 C 语言实现程序的多态性》:
http://www.ibm.com/developerworks/cn/linux/l-cn-cpolym/index.html?ca=drs-
(4) 书籍《Object-Oriented Programming With ANSI-C》
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- c语言实现封装,继承和多态
- c语言实现封装,继承和多态
- c语言实现封装,继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- c语言实现封装,继承和多态
- C语言实现封装、继承和多态
- C语言实现C++的封装继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- C语言实现封装、继承和多态
- 模拟语音加密的置乱技术简介
- lsof 查看打开文件状态
- iOS笔记
- 深度学习文献阅读笔记(6)
- 做网站:myeclipse+tomcat+mysql环境搭建
- C语言实现封装、继承和多态
- Sumsets(递推)
- 使用Eclipse一点心得
- CollectionView实现瀑布流(swift)
- GNU assembler not found, install/update gas-preprocessor
- 20160114html学习笔记表单框架颜色脚本字符实体
- leetcode刷题,总结, 记录,备忘326
- 内存泄漏
- jenkins资料