C 语言中实现数据与方法的封装

来源:互联网 发布:jdk 8u101 linux x64 编辑:程序博客网 时间:2024/04/19 10:16

  出处:http://blog.csdn.net/justme0/article/details/10055441

在 C 语言中可以用结构体代替类,用函数指针代替成员方法,实现数据成员与成员方法的封装,在客户端写出的程序与 C++ 类似,唯一的不同是 C 语言中调用函数指针成员时必须将本对象的地址传给函数,因为 C 语言中各函数的地位是相同的。

       本文以模仿 STL 中的 vector 类写了一个 C 语言的 vector 结构体,程序如下:

1. vector 的接口

[cpp] view plaincopyprint?
  1. /******************************************************************** 
  2.     created:    2013/08/19 
  3.     created:    19:8:2013   0:09 
  4.     file base:  vector 
  5.     file ext:   h 
  6.     author:     Justme0 (http://blog.csdn.net/Justme0) 
  7.      
  8.     purpose:    vector 结构体的定义 
  9. *********************************************************************/  
  10.   
  11. #ifndef _VECTOR_H_  
  12. #define _VECTOR_H_  
  13.   
  14. typedef struct vector vector;  
  15.   
  16. typedef char            vec_value_type;  
  17. typedef vec_value_type* vec_pointer;  
  18. typedef vec_value_type* vec_iterator;  
  19. typedef unsigned int    vec_size_type;  
  20.   
  21. struct vector {  
  22.     /* 
  23.     ** 获取下标为 index 的元素 
  24.     */  
  25.     vec_value_type (*get_at)(vector *pvec, const int index);  
  26.   
  27.     /* 
  28.     ** 设置下标为 index 处的元素为 elem 
  29.     */  
  30.     void (*set_at)(vector *pvec, const int index, const vec_value_type elem);  
  31.   
  32.     vec_iterator (*begin)(vector *pvec);  
  33.     vec_iterator (*end)(vector *pvec);  
  34.   
  35.     vec_value_type (*front)(vector *pvec);  
  36.     vec_value_type (*back)(vector *pvec);  
  37.   
  38.     int (*size)(vector *pvec);  
  39.     int (*capacity)(vector *pvec);  
  40.     int (*empty)(vector *pvec);  
  41.   
  42.     void (*insert_n)(vector *pvec, const vec_iterator position, const vec_size_type n, const vec_value_type elem);  
  43.     vec_iterator (*earse_pos)(vector *pvec, const vec_iterator position);  
  44.     vec_iterator (*earse_int)(vector *pvec, const vec_iterator first, const vec_iterator last);  
  45.     void (*clear)(vector *pvec);  
  46.     void (*push_back)(vector *pvec, const vec_value_type elem);  
  47.     void (*pop_back)(vector *pvec);  
  48.   
  49.     vec_iterator _start;  
  50.     vec_iterator _finish;  
  51.     vec_iterator _end_of_storage;  
  52. };  
  53.   
  54. void vec_construct(vector *pvec);  
  55. void vec_construct_n(vector *pvec, const int size);  
  56.   
  57. void vec_destruct(vector *pvec);  
  58.   
  59. #endif  

2. vector 的实现

[cpp] view plaincopyprint?
  1. /******************************************************************** 
  2.     created:    2013/08/19 
  3.     created:    19:8:2013   0:09 
  4.     file base:  vector 
  5.     file ext:   c 
  6.     author:     Justme0 (http://blog.csdn.net/Justme0) 
  7.      
  8.     purpose:    vector 的实现 
  9. *********************************************************************/  
  10.   
  11. #include "vector.h"  
  12. #include <math.h>  
  13. #include <stdlib.h>  
  14. #include <assert.h>  
  15.   
  16. #define CHECK_BORDER assert(pvec->_finish >= pvec->_start && pvec->_end_of_storage >= pvec->_start)  
  17.   
  18. static vec_iterator copy(vec_iterator first, vec_iterator last, vec_iterator result) {  
  19.     vec_iterator src = first;  
  20.     vec_iterator dst = result;  
  21.     for (; src != last; ++src, ++dst) {  
  22.         *dst = *src;  
  23.     }  
  24.     return dst;  
  25. }  
  26.   
  27. static vec_value_type _get_at(vector *pvec, int index) {  
  28.     return *(pvec->begin(pvec) + index);  
  29. }  
  30.   
  31. static void _set_at(vector *pvec, int index, vec_value_type elem) {  
  32.     pvec->_start[index] = elem;  
  33. }  
  34.   
  35. static vec_iterator _begin(vector *pvec) {  
  36.     return pvec->_start;  
  37. }  
  38.   
  39. static vec_iterator _end(vector *pvec) {  
  40.     return pvec->_finish;  
  41. }  
  42.   
  43. static vec_value_type _front(vector *pvec) {  
  44.     return *pvec->begin(pvec);  
  45. }  
  46.   
  47. static vec_value_type _back(vector *pvec) {  
  48.     return *(pvec->end(pvec) - 1);  
  49. }  
  50.   
  51. static int _size(vector *pvec) {  
  52.     return pvec->end(pvec) - pvec->begin(pvec);  
  53. }  
  54.   
  55. static int _capacity(vector *pvec) {  
  56.     return pvec->_end_of_storage - pvec->begin(pvec);  
  57. }  
  58.   
  59. static int _empty(vector *pvec) {  
  60.     return pvec->begin(pvec) == pvec->end(pvec);  
  61. }  
  62.   
  63.   
  64. static void _insert_n(vector *pvec, vec_iterator position, vec_size_type n, const vec_value_type elem) {  
  65.     vec_size_type old_size = 0;  
  66.     vec_size_type new_size = 0;  
  67.     int inset_index = 0;  
  68.     vec_iterator ite = NULL;  
  69.   
  70.     assert(pvec->_start <= position && position <= pvec->end(pvec));  
  71.     CHECK_BORDER;  
  72.   
  73.     if (0 == n) {  
  74.         return ;  
  75.     }  
  76.   
  77.     inset_index = position - pvec->_start;  
  78.     old_size = pvec->size(pvec);  
  79.     new_size = old_size + n;  
  80.   
  81.     // 先检查剩余空间是否足够,不够则扩容  
  82.     if ((vec_size_type)(pvec->_end_of_storage - pvec->_finish) < n) {  
  83.         const vec_size_type new_capacity = old_size + __max(old_size, n);  
  84.   
  85.         vec_value_type *new_base = (vec_value_type *)realloc(pvec->_start, new_capacity * sizeof(vec_value_type));  
  86.         if (NULL == new_base) {  
  87.             exit(OVERFLOW); // 此时原来的空间将发生内存泄漏  
  88.         }  
  89.         pvec->_start = new_base;  
  90.         pvec->_end_of_storage = pvec->_start + new_capacity;  
  91.     }  
  92.     pvec->_finish = pvec->_start + new_size;  
  93.   
  94.     position = pvec->_start + inset_index;  
  95.     // 移动元素  
  96.     for (ite = pvec->_finish; ite >= position + n; --ite) {  
  97.         *ite = *(ite - n);  
  98.     }  
  99.     // 插入n个新元素  
  100.     for (; ite >= position; --ite) {  
  101.         *ite = elem;  
  102.     }  
  103. }  
  104.   
  105. static vec_iterator _earse_pos(vector *pvec, const vec_iterator position) {  
  106.     if (position + 1 != pvec->end(pvec)) {  
  107.         copy(position + 1, pvec->_finish, position);  
  108.     }  
  109.     --pvec->_finish;  
  110.     return position;  
  111. }  
  112.   
  113. static vec_iterator _earse_int(vector *pvec, const vec_iterator first, const vec_iterator last) {  
  114.     vec_iterator i = copy(last, pvec->_finish, first);  
  115.     pvec->_finish -= last - first;  
  116.   
  117.     return first;  
  118. }  
  119.   
  120. static void _clear(vector *pvec) {  
  121.     pvec->earse_int(pvec, pvec->begin(pvec), pvec->end(pvec));  
  122. }  
  123.   
  124. static void _push_back(vector *pvec, const vec_value_type elem) {  
  125.     CHECK_BORDER;  
  126.   
  127.     _insert_n(pvec, pvec->end(pvec), 1, elem);  
  128. }  
  129.   
  130. static void _pop_back(vector *pvec) {  
  131.     pvec->earse_pos(pvec, pvec->end(pvec) - 1);  
  132. }  
  133.   
  134.   
  135. static void set(vector *pvec) {  
  136.     pvec->_finish = NULL;  
  137.     pvec->_start = NULL;  
  138.     pvec->_end_of_storage = NULL;  
  139.   
  140.     pvec->get_at = _get_at;  
  141.     pvec->set_at = _set_at;  
  142.   
  143.     pvec->begin = _begin;  
  144.     pvec->end = _end;  
  145.   
  146.     pvec->front = _front;  
  147.     pvec->back = _back;  
  148.   
  149.     pvec->size = _size;  
  150.     pvec->capacity = _capacity;  
  151.     pvec->empty = _empty;  
  152.   
  153.     pvec->insert_n = _insert_n;  
  154.     pvec->earse_pos = _earse_pos;  
  155.     pvec->earse_int = _earse_int;  
  156.     pvec->clear = _clear;  
  157.     pvec->push_back = _push_back;  
  158.     pvec->pop_back = _pop_back;  
  159. }  
  160.   
  161. static void reset(vector *pvec) {  
  162.     pvec->_finish = NULL;  
  163.     pvec->_start = NULL;  
  164.     pvec->_end_of_storage = NULL;  
  165.   
  166.     pvec->get_at = NULL;  
  167.     pvec->set_at = NULL;  
  168.   
  169.     pvec->begin = NULL;  
  170.     pvec->end = NULL;  
  171.   
  172.     pvec->front = NULL;  
  173.     pvec->back = NULL;  
  174.   
  175.     pvec->size = NULL;  
  176.     pvec->capacity = NULL;  
  177.     pvec->empty = NULL;  
  178.   
  179.     pvec->insert_n = NULL;  
  180.     pvec->earse_pos = NULL;  
  181.     pvec->earse_int = NULL;  
  182.     pvec->clear = NULL;  
  183.     pvec->push_back = NULL;  
  184.     pvec->pop_back = NULL;  
  185. }  
  186.   
  187. void vec_construct(vector *pvec) {  
  188.     set(pvec);  
  189. }  
  190.   
  191. void vec_construct_n(vector *pvec, const int size) {  
  192.     set(pvec);  
  193.   
  194.     pvec->_start = (vec_iterator)malloc(size * sizeof(*pvec->_start));  
  195.     if (NULL == pvec->_start) {  
  196.         // TODO:  
  197.         exit(OVERFLOW);  
  198.     }  
  199.   
  200.     pvec->_finish = pvec->_start + size;  
  201.     pvec->_end_of_storage = pvec->_finish;  
  202. }  
  203.   
  204. void vec_destruct(vector *pvec) {  
  205.     free(pvec->_start);  
  206.   
  207.     reset(pvec);  
  208. }  

3. 测试程序

[cpp] view plaincopyprint?
  1. /******************************************************************** 
  2.     created:    2013/08/19 
  3.     created:    19:8:2013   0:10 
  4.     file base:  test 
  5.     file ext:   c 
  6.     author:     Justme0 (http://blog.csdn.net/Justme0) 
  7.      
  8.     purpose:    vector 的测试程序 
  9. *********************************************************************/  
  10.   
  11. #include "vector.h"  
  12. #include <stdio.h>  
  13.   
  14. void output(vector *pvec) {  
  15.     vec_iterator iter;  
  16.     for (iter = pvec->begin(pvec); iter != pvec->end(pvec); ++iter) {  
  17.         printf("%c\n", *iter);  
  18.     }  
  19. }  
  20.   
  21. int main(int argc, char **argv) {  
  22.     char ch = 'A';  
  23.     int cnt = 5;  
  24.   
  25.     vector my_vec;  
  26.     vec_construct(&my_vec);  
  27.   
  28.     while (cnt--) {  
  29.         my_vec.push_back(&my_vec, ch++);  
  30.     }  
  31.     output(&my_vec);  
  32.   
  33.     puts("set [2]: '2'");  
  34.     my_vec.set_at(&my_vec, 2, '2');  
  35.     output(&my_vec);  
  36.   
  37.     my_vec.empty(&my_vec) ? puts("empty") : puts("not empty");  
  38.   
  39.     puts("pop_back...");  
  40.     my_vec.pop_back(&my_vec);  
  41.     output(&my_vec);  
  42.     printf("size is %d\n", my_vec.size(&my_vec));  
  43.   
  44.     printf("back is '%c'\n", my_vec.back(&my_vec));  
  45.   
  46.     puts("clear...");  
  47.     my_vec.clear(&my_vec);  
  48.   
  49.     my_vec.empty(&my_vec) ? puts("empty") : puts("not empty");  
  50.   
  51.     vec_destruct(&my_vec);  
  52.   
  53.     return 0;  
  54. }  

4. 运行结果

[plain] view plaincopyprint?
  1. A  
  2. B  
  3. C  
  4. D  
  5. E  
  6. set [2]: '2'  
  7. A  
  8. B  
  9. 2  
  10. D  
  11. E  
  12. not empty  
  13. pop_back...  
  14. A  
  15. B  
  16. 2  
  17. D  
  18. size is 4  
  19. back is 'D'  
  20. clear...  
  21. empty  
  22. 请按任意键继续. . .  

       1、在测试程序中可以看到,定义一个结构体后,必须紧跟着用函数 construct 将对象的成员赋值以初始化,我称这个过程为“构造”。

       2、最后必须显示调用 destruct 函数将对象“析构”,释放对象 malloc 的空间。


       我将这个程序给某个 C++ 游戏程序员看,被他一阵批,说我的程序最大的缺点就是 不是面向对象;没有一个企业会让这份程序通过;“你写的是 Objective-C 形式”。桑心啊,我只好贴在这独自欣赏了。