C语言下的封装继承与多态.docx_第1页
C语言下的封装继承与多态.docx_第2页
C语言下的封装继承与多态.docx_第3页
C语言下的封装继承与多态.docx_第4页
C语言下的封装继承与多态.docx_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言下的封装、继承与多态 上次课,钱SIR提到,Liux下面也有很多用C实现的面向对象的结构。比较感觉兴趣,就在网上查了一些资料,原来C语言模拟实现面向对象语言所具有的特性:多态,继承,封装,也是一件很简单的事儿。并且现在很多开源软件都了用C语言实现了这几个特性,包括大型开源数据库系统postgreSQL,可移植的C语言面向对象框架GObject。在自己机器上实践了下,感叹C语言的灵活与强大!总结一下,以便交流:一、基础知识(1)结构体结构体可以嵌套,因而可以把一个结构体当成另一个结构体的成员,如:cpp view plaincopyprint?1. struct Point 2. int x; 3. int y; 4. ; cpp view plaincopyprint?1. struct Circle 2. struct Point point_; 3. int radius; 4. ; 该结构体与以下定义完全一样(包括内存布置都一样cpp view plaincopyprint?1. struct Circle 2. int x; 3. int y; 4. int radius; 5. ; (2)void *指针是整个 C 语言的精髓所在。而你也一直敬畏着指针,又爱又恨地使用着它。许多教材都告诉你,int *叫做指向整型的指针,而 char *是指向字符型的指针,等等等等不一而足。然而这里有一个另类的指针家族成员void *。不要按照通常的命名方式叫它做指向void 类型的指针,它的正式的名字叫做:可以指向任意类型的指针。(3)C中的参数个数可变函数 可变参数函数的原型声明:cpp view plaincopyprint?1. type VAFunction(type arg1, type arg2, ); 参数可以分为两部分:个数确定的固定参数和个数可变的可选参数。函数至少需要一个固定参数,固定参数的声明和普通函数一样;可选参数由于个数不确定,声明时用.表示。固定参数和可选参数公同构成一个函数的参数列表。标准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_ptr, type ); 3. void va_end ( va_list arg_ptr ); 在这些宏中,va就是variable argument(可变参数)的意思;arg_ptr 是指向可变参数表的指针;prev_param 指可变参数表的前一个固定参数;type 为可变参数的类型。va_list 也是一个宏,其定义为typedef char * va_list,实质上是一char型指针。具体用法可以参考:/space.php?uid=9174178&do=blog&cuid=484548二、封装封装的主要含义是隐藏内部的行为和信息,使用者只用看到对外提供的接口和公开的信息。在C语言中的实现方法:把私有数据信息放在一个不透明的priv变量或者结构体中,只有类的实现代码才知道priv或者结构体的真正定义。例如:头文件:cpp view plaincopyprint?1. /=头文件:Point.h文件= 2. #ifndef POINT_H 3. #define POINT_H 4. typedef struct Point point; 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 源文件cpp 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_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. 测试文件:cpp view plaincopyprint?1. int main() 2. 3. point* p = 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. 在测试代码中,注释掉的一部分是编译不过的,因为我们已经把pointPrivate结构体的定义隐藏了。而且必须使用new_point来创建point结构对象,否则无法初始化point结构体中的pp成员变量。有意思的是:这段代码生成的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. #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 * 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); */ 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 = _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 = 50. sizeof(struct Point), Point_ctor, 0, Point_draw 51. ; 52. const void * Point = & _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 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. #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. 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. ; 95. const void * Circle = & _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 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, & ap); 119. va_end(ap); 120. 121. return p; 122. 123. void delete (void * self) 124. const struct Base * cp = self; 125. if (self & * cp & (* cp) - dtor) 126. self = (* cp) - dtor(self); 127. free(self); 128. 129. void draw (const void * self) 130. const struct Base * const * cp = self; 131. assert(s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论