收藏 分享(赏)

C语言下的封装 继承 与多态.docx

上传人:wspkg9802 文档编号:6975245 上传时间:2019-04-29 格式:DOCX 页数:10 大小:66.76KB
下载 相关 举报
C语言下的封装 继承 与多态.docx_第1页
第1页 / 共10页
C语言下的封装 继承 与多态.docx_第2页
第2页 / 共10页
C语言下的封装 继承 与多态.docx_第3页
第3页 / 共10页
C语言下的封装 继承 与多态.docx_第4页
第4页 / 共10页
C语言下的封装 继承 与多态.docx_第5页
第5页 / 共10页
点击查看更多>>
资源描述

1、C 语言下的封装、继承与多态 上次课,钱 SIR 提到,Liux 下面也有很多用 C 实现的面向对象的结构。比较感觉兴趣,就在网上查了一些资料,原来 C 语言模拟实现面向对象语言所具有的特性:多态,继承,封装,也是一件很简单的事儿。并且现在很多开源软件都了用 C 语言实现了这几个特性,包括大型开源数据库系统 postgreSQL,可移植的 C 语言面向对象框架 GObject。在自己机器上实践了下,感叹 C 语言的灵活与强大!总结一下,以便交流:一、基础知识(1)结构体结构体可以嵌套,因而可以把一个结构体当成另一个结构体的成员,如:cpp view plaincopyprint?1. stru

2、ct Point 2. int x; 3. int y; 4. ; struct Point int x; int y;cpp view plaincopyprint?1. struct Circle 2. struct Point point_; 3. int radius; 4. ; struct Circle struct Point point_; int radius; ; 该结构体与以下定义完全一样(包括内存布置都一样cpp view plaincopyprint?1. struct Circle 2. int x; 3. int y; 4. int radius; 5. ; st

3、ruct Circle int x; int y; int radius; ;(2)void *指针是整个 C 语言的精髓所在。而你也一直敬畏着指针,又爱又恨地使用着它。许多教材都告诉你,int *叫做指向整型的指针,而 char *是指向字符型的指针,等等等等不一而足。然而这里有一个另类的指针家族成员void *。不要按照通常的命名方式叫它做指向void 类型的指针,它的正式的名字叫做:可以指向任意类型的指针。(3)C 中的参数个数可变函数 可变参数函数的原型声明:cpp view plaincopyprint?1. type VAFunction(type arg1, type arg2,

4、 ); type VAFunction(type arg1, type参数可以分为两部分:个数确定的固定参数和个数可变的可选参数。函数至少需要一个固定参数,固定参数的声明和普通函数一样;可选参数由于个数不确定,声明时用“.“表示。固定参数和可选参数公同构成一个函数的参数列表。标准 C/C+包含头文件 stdarg.h,该头文件中定义了操作不定变量的相关宏:cpp view plaincopyprint?1. void va_start ( va_list arg_ptr, prev_param ); /* ANSI version */ 2. type va_arg ( va_list arg

5、_ptr, type ); 3. void va_end ( va_list arg_ptr ); void va_start ( va_list arg_ptrtype va_arg ( va_list arg_ptr, void va_end ( va_list arg_ptr )在这些宏中,va 就是 variable argument(可变参数) 的意思;arg_ptr 是指向可变参数表的指针;prev_param 指可变参数表的前一个固定参数;type 为可变参数的类型。va_list 也是一个宏,其定义为 typedef char * va_list,实质上是一 char 型指针。

6、具体用法可以参考:http:/ 5. typedef struct pointPrivate pointPrivate; 6. struct Point 7.8. 9. struct pointPrivate *pp; 10. int get_x(point *point_); 11. int get_y(point *point_); 12. point * new_point(int x,int y); 13. 14. #endif 源文件/=头 文 件 : Point.h文 件 =#ifndef POINT_H#define POINT_Htypedef struct Point poi

7、nt;typedef struct pointPrivate poistcpp view plaincopyprint?1. /=C 文件:Point.c 文件= 2. #include “Point.h“ 3. #include 4. struct pointPrivate; 5. int x; 6. int y; 7. ; 8.9. int get_x(point *point_) 10. return point_-pp-x; 11. 12.13. int get_y(point *point_) 14. return point_-pp-y; 15. 16.17. point* new

8、_point(int x,int y) 18. point* p=(point*)malloc(sizeof(point); 19. p-pp=(pointPrivate*)malloc(sizeof(pointPrivate); 20. p-pp-x=x; 21. p-pp-y=y; 22. return p; 23. 测试文件:/=C文 件 :Point.c文 件 =#include “Point.h“#includestruct pointPrivate;int x; int y;cpp view plaincopyprint?1. int main() 2. 3. point* p =

9、 new_point(1,2); 4. /printf(“x:%d,y:%dn“,p-pp-x,p-pp-y); 5. printf(“x:%d,y:%dn“,get_x(p),get_y(p); 6. 在测试代码中,注释掉的一部分是编译不过的,因为我int main()point* p = new_point(1,/printf(“x:%d,y:%dn“,printf(“x:%d,y:%dn“,ge们已经把 pointPrivate 结构体的定义隐藏了。而且必须使用 new_point 来创建 point 结构对象,否则无法初始化 point 结构体中的 pp 成员变量。有意思的是:这段代码

10、生成的 exe 文件可能会被 360 误认为病毒。三、继承在 C 语言中,可以利用“结构在内存中的布局与结构的声明具有一致的顺序 ”这一事实实现继承。 比如我们要设计一个作图工具,其中可能涉及到的对象有 Point(点),Circle(圆),由于圆是由点组成的,所有可以看成 Circle 继承自 Point。另外,Point 和 Circle 都需要空间申请,空间释放等操作,所有他们有共同的基类 Base。cpp view plaincopyprint?1. /基类 Base 的内部头文件 Base.r,对外隐藏 2. #ifndef BASE_R 3. #define BASE_R 4. #

11、include 5. struct Base 6. size_t size; 7. void * (* ctor) (void * self, va_list * app);/构造函数 8. void * (* dtor) (void * self); /析构函数 9. void (* draw) (const void * self);/作图函数 10. ; 11. #endif 12.13. /Point 的内部头文件 Point.r,对外隐藏 14. #ifndef POINT_R 15. #define POINT_R 16. struct Point 17. const void *

12、 base; /继承 Base 类,基类指针,放在第一个位置, const 是防止修改 18. int x, y; /坐标 19. ; 20. #define x(p) (const struct Point *)(p) - x) 21. #define y(p) (const struct Point *)(p) - y) 22. #endif 23.24. /Point 的头文件 Point.h(对外提供接口) 25. #ifndef POINT_H 26. #define POINT_H 27. extern const void * Point; /* new(Point, x, y)

13、; */ 28. void move (void * point, int dx, int dy); 29. #endif 30.31. /Point 的源文件 Point.c 32. #include 33. #include “Point.h“ 34. #include “Point.r“ 35. #include “new.h“ 36. #include “Base.r“ 37. /*Point 类自己的构造函数*/ 38. static void * Point_ctor (void * _self, va_list * app) 39. struct Point * self = _

14、self; 40. self - x = va_arg(* app, int); 41. self - y = va_arg(* app, int); 42. return self; 43. 44. /*Point 类自己的绘图函数*/ 45. static void Point_draw (const void * _self) 46. const struct Point * self = _self; 47. printf(“Point at %d,%dn“, self - x, self - y); 48. 49. static const struct Base _Point =

15、50. sizeof(struct Point), Point_ctor, 0, Point_draw 51. ; 52. const void * Point = 53. void move (void * _self, int dx, int dy) 54. struct Point * self = _self; 55. self - x += dx, self - y += dy; 56. 57.58. /Circle 内部头文件 Circle.r,对外隐藏 59. #ifndef CIRCLE_R 60. #define CIRCLE_R 61. #include “Point.r“

16、 62. struct Circle 63. const struct Point _; /继承 Point 类,需放在第一位 64. int rad; 65. ; 66. #endif 67.68. /Circle 的头文件 Circle.h(对外提供接口) 69. #ifndef CIRCLE_H 70. #define CIRCLE_H 71. #include “Point.h“ 72. extern const void * Circle; /* new(Circle, x, y, rad) */ 73. #endif 74.75. /Circle 的源文件 Circle.c 76.

17、 #include 77. #include “Circle.h“ 78. #include “Circle.r“ 79. #include “new.h“ 80. #include “Base.r“ 81. /*Circle 类自己的构造函数*/ 82. static void * Circle_ctor (void * _self, va_list * app) 83. struct Circle * self = (const struct Base *) Point) - ctor(_self, app); 84. self - rad = va_arg(* app, int); 85

18、. return self; 86. 87. /*Circle 类自己的绘图函数*/ 88. static void Circle_draw (const void * _self) 89. const struct Circle * self = _self; 90. printf(“circle at %d,%d rad %dn“,x(self), y(self), self - rad); 91. 92. static const struct Base _Circle = 93. sizeof(struct Circle), Circle_ctor, 0, Circle_draw 94

19、. ; 95. const void * Circle = 96.97. /内存管理类头文件 new.h(对外提供接口) 98. #ifndef NEW_H 99. #define NEW_H 100. void * new (const void * base, .); 101. void delete (void * item); 102. void draw (const void * self); 103. #endif 104.105. /内存管理类的源文件:new.c 106. #include 107. #include 108. #include 109. #include “

20、Base.r“ 110. void * new (const void * _class, .) 111. const struct Base * base = _class; 112. void * p = calloc(1, base - size); 113. assert(p); 114. * (const struct Base *) p = base; 115. if (base - ctor) 116. va_list ap; 117. va_start(ap, _class); 118. p = base - ctor(p, 119. va_end(ap); 120. 121.

21、 return p; 122. 123. void delete (void * self) 124. const struct Base * cp = self; 125. if (self 127. free(self); 128. 129. void draw (const void * self) 130. const struct Base * const * cp = self; 131. assert(self 132. (* cp) - draw(self); 133. 四、多态可以是用 C 语言中的万能指针 void* 实现多态,/基 类 Base的 内 部 头 文 件 Ba

22、se.r, 对#ifndef BASE_R#define BASE_R#include struct Base size_t size;接上面的例子:cpp view plaincopyprint?1. #include “Circle.h“ 2. #include “new.h“ 3. int main (int argc, char * argv) 4. 5. void * p; 6. int i; 7. for(i=0; i2; i+) 8. 9. if(i=0) 10. p = new(Circle, 1, 2, 3); 11. else 12. p = new(Point, 1, 2

23、); 13. draw(p); 14. move(p, 10, 20); 15. draw(p); 16. delete(p); 17. 18. return 0; 19. 输出结果:#include “Circle.h“#include “new.h“int main (int argc, char * argvoid * p;int i;circle at 1,2 rad 3circle at 11,22 rad 3Point at 1,2Point at 11,22五、总结面向对象是一种程序设计思想,而 C 语言则是一种编程语言。也许它并不是专门为了面向对象编程而设计,但是这绝不意味着它不能实现面向对象的程序设计。当然以上所展示的这几个操作,如果是用别的编程语言,可能只要寥寥几行就可以完成,但是 C 语言想告诉我们的是:也许我不擅长,但是并不意味着我做不到。注:有些头文件名被 csdn 误认为内部命令,而变很很诡异,请以所下载的代码为准。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报