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 的接口
- /********************************************************************
- created: 2013/08/19
- created: 19:8:2013 0:09
- file base: vector
- file ext: h
- author: Justme0 (http://blog.csdn.net/Justme0)
- purpose: vector 结构体的定义
- *********************************************************************/
- #ifndef _VECTOR_H_
- #define _VECTOR_H_
- typedef struct vector vector;
- typedef char vec_value_type;
- typedef vec_value_type* vec_pointer;
- typedef vec_value_type* vec_iterator;
- typedef unsigned int vec_size_type;
- struct vector {
- /*
- ** 获取下标为 index 的元素
- */
- vec_value_type (*get_at)(vector *pvec, const int index);
- /*
- ** 设置下标为 index 处的元素为 elem
- */
- void (*set_at)(vector *pvec, const int index, const vec_value_type elem);
- vec_iterator (*begin)(vector *pvec);
- vec_iterator (*end)(vector *pvec);
- vec_value_type (*front)(vector *pvec);
- vec_value_type (*back)(vector *pvec);
- int (*size)(vector *pvec);
- int (*capacity)(vector *pvec);
- int (*empty)(vector *pvec);
- void (*insert_n)(vector *pvec, const vec_iterator position, const vec_size_type n, const vec_value_type elem);
- vec_iterator (*earse_pos)(vector *pvec, const vec_iterator position);
- vec_iterator (*earse_int)(vector *pvec, const vec_iterator first, const vec_iterator last);
- void (*clear)(vector *pvec);
- void (*push_back)(vector *pvec, const vec_value_type elem);
- void (*pop_back)(vector *pvec);
- vec_iterator _start;
- vec_iterator _finish;
- vec_iterator _end_of_storage;
- };
- void vec_construct(vector *pvec);
- void vec_construct_n(vector *pvec, const int size);
- void vec_destruct(vector *pvec);
- #endif
2. vector 的实现
- /********************************************************************
- created: 2013/08/19
- created: 19:8:2013 0:09
- file base: vector
- file ext: c
- author: Justme0 (http://blog.csdn.net/Justme0)
- purpose: vector 的实现
- *********************************************************************/
- #include "vector.h"
- #include <math.h>
- #include <stdlib.h>
- #include <assert.h>
- #define CHECK_BORDER assert(pvec->_finish >= pvec->_start && pvec->_end_of_storage >= pvec->_start)
- static vec_iterator copy(vec_iterator first, vec_iterator last, vec_iterator result) {
- vec_iterator src = first;
- vec_iterator dst = result;
- for (; src != last; ++src, ++dst) {
- *dst = *src;
- }
- return dst;
- }
- static vec_value_type _get_at(vector *pvec, int index) {
- return *(pvec->begin(pvec) + index);
- }
- static void _set_at(vector *pvec, int index, vec_value_type elem) {
- pvec->_start[index] = elem;
- }
- static vec_iterator _begin(vector *pvec) {
- return pvec->_start;
- }
- static vec_iterator _end(vector *pvec) {
- return pvec->_finish;
- }
- static vec_value_type _front(vector *pvec) {
- return *pvec->begin(pvec);
- }
- static vec_value_type _back(vector *pvec) {
- return *(pvec->end(pvec) - 1);
- }
- static int _size(vector *pvec) {
- return pvec->end(pvec) - pvec->begin(pvec);
- }
- static int _capacity(vector *pvec) {
- return pvec->_end_of_storage - pvec->begin(pvec);
- }
- static int _empty(vector *pvec) {
- return pvec->begin(pvec) == pvec->end(pvec);
- }
- static void _insert_n(vector *pvec, vec_iterator position, vec_size_type n, const vec_value_type elem) {
- vec_size_type old_size = 0;
- vec_size_type new_size = 0;
- int inset_index = 0;
- vec_iterator ite = NULL;
- assert(pvec->_start <= position && position <= pvec->end(pvec));
- CHECK_BORDER;
- if (0 == n) {
- return ;
- }
- inset_index = position - pvec->_start;
- old_size = pvec->size(pvec);
- new_size = old_size + n;
- // 先检查剩余空间是否足够,不够则扩容
- if ((vec_size_type)(pvec->_end_of_storage - pvec->_finish) < n) {
- const vec_size_type new_capacity = old_size + __max(old_size, n);
- vec_value_type *new_base = (vec_value_type *)realloc(pvec->_start, new_capacity * sizeof(vec_value_type));
- if (NULL == new_base) {
- exit(OVERFLOW); // 此时原来的空间将发生内存泄漏
- }
- pvec->_start = new_base;
- pvec->_end_of_storage = pvec->_start + new_capacity;
- }
- pvec->_finish = pvec->_start + new_size;
- position = pvec->_start + inset_index;
- // 移动元素
- for (ite = pvec->_finish; ite >= position + n; --ite) {
- *ite = *(ite - n);
- }
- // 插入n个新元素
- for (; ite >= position; --ite) {
- *ite = elem;
- }
- }
- static vec_iterator _earse_pos(vector *pvec, const vec_iterator position) {
- if (position + 1 != pvec->end(pvec)) {
- copy(position + 1, pvec->_finish, position);
- }
- --pvec->_finish;
- return position;
- }
- static vec_iterator _earse_int(vector *pvec, const vec_iterator first, const vec_iterator last) {
- vec_iterator i = copy(last, pvec->_finish, first);
- pvec->_finish -= last - first;
- return first;
- }
- static void _clear(vector *pvec) {
- pvec->earse_int(pvec, pvec->begin(pvec), pvec->end(pvec));
- }
- static void _push_back(vector *pvec, const vec_value_type elem) {
- CHECK_BORDER;
- _insert_n(pvec, pvec->end(pvec), 1, elem);
- }
- static void _pop_back(vector *pvec) {
- pvec->earse_pos(pvec, pvec->end(pvec) - 1);
- }
- static void set(vector *pvec) {
- pvec->_finish = NULL;
- pvec->_start = NULL;
- pvec->_end_of_storage = NULL;
- pvec->get_at = _get_at;
- pvec->set_at = _set_at;
- pvec->begin = _begin;
- pvec->end = _end;
- pvec->front = _front;
- pvec->back = _back;
- pvec->size = _size;
- pvec->capacity = _capacity;
- pvec->empty = _empty;
- pvec->insert_n = _insert_n;
- pvec->earse_pos = _earse_pos;
- pvec->earse_int = _earse_int;
- pvec->clear = _clear;
- pvec->push_back = _push_back;
- pvec->pop_back = _pop_back;
- }
- static void reset(vector *pvec) {
- pvec->_finish = NULL;
- pvec->_start = NULL;
- pvec->_end_of_storage = NULL;
- pvec->get_at = NULL;
- pvec->set_at = NULL;
- pvec->begin = NULL;
- pvec->end = NULL;
- pvec->front = NULL;
- pvec->back = NULL;
- pvec->size = NULL;
- pvec->capacity = NULL;
- pvec->empty = NULL;
- pvec->insert_n = NULL;
- pvec->earse_pos = NULL;
- pvec->earse_int = NULL;
- pvec->clear = NULL;
- pvec->push_back = NULL;
- pvec->pop_back = NULL;
- }
- void vec_construct(vector *pvec) {
- set(pvec);
- }
- void vec_construct_n(vector *pvec, const int size) {
- set(pvec);
- pvec->_start = (vec_iterator)malloc(size * sizeof(*pvec->_start));
- if (NULL == pvec->_start) {
- // TODO:
- exit(OVERFLOW);
- }
- pvec->_finish = pvec->_start + size;
- pvec->_end_of_storage = pvec->_finish;
- }
- void vec_destruct(vector *pvec) {
- free(pvec->_start);
- reset(pvec);
- }
3. 测试程序
- /********************************************************************
- created: 2013/08/19
- created: 19:8:2013 0:10
- file base: test
- file ext: c
- author: Justme0 (http://blog.csdn.net/Justme0)
- purpose: vector 的测试程序
- *********************************************************************/
- #include "vector.h"
- #include <stdio.h>
- void output(vector *pvec) {
- vec_iterator iter;
- for (iter = pvec->begin(pvec); iter != pvec->end(pvec); ++iter) {
- printf("%c\n", *iter);
- }
- }
- int main(int argc, char **argv) {
- char ch = 'A';
- int cnt = 5;
- vector my_vec;
- vec_construct(&my_vec);
- while (cnt--) {
- my_vec.push_back(&my_vec, ch++);
- }
- output(&my_vec);
- puts("set [2]: '2'");
- my_vec.set_at(&my_vec, 2, '2');
- output(&my_vec);
- my_vec.empty(&my_vec) ? puts("empty") : puts("not empty");
- puts("pop_back...");
- my_vec.pop_back(&my_vec);
- output(&my_vec);
- printf("size is %d\n", my_vec.size(&my_vec));
- printf("back is '%c'\n", my_vec.back(&my_vec));
- puts("clear...");
- my_vec.clear(&my_vec);
- my_vec.empty(&my_vec) ? puts("empty") : puts("not empty");
- vec_destruct(&my_vec);
- return 0;
- }
4. 运行结果
- A
- B
- C
- D
- E
- set [2]: '2'
- A
- B
- 2
- D
- E
- not empty
- pop_back...
- A
- B
- 2
- D
- size is 4
- back is 'D'
- clear...
- empty
- 请按任意键继续. . .
1、在测试程序中可以看到,定义一个结构体后,必须紧跟着用函数 construct 将对象的成员赋值以初始化,我称这个过程为“构造”。
2、最后必须显示调用 destruct 函数将对象“析构”,释放对象 malloc 的空间。
我将这个程序给某个 C++ 游戏程序员看,被他一阵批,说我的程序最大的缺点就是 不是面向对象;没有一个企业会让这份程序通过;“你写的是 Objective-C 形式”。桑心啊,我只好贴在这独自欣赏了。
- C 语言中实现数据与方法的封装
- C 语言中实现数据与方法的封装
- 用C语言封装数据与方法
- 用C语言封装数据与方法
- 用C语言封装数据与方法
- C语言实现MAC帧的封装与解封装
- C语言实现C++的封装继承与多态
- 在C中实现对struct内部数据的封装
- c语言数据封装
- C语言中strcat的实现方法
- C语言实现封装
- C语言实现封装
- C语言中实现数据与算法分离
- 利用strstr与atoi的结合实现一个C语言获取文件中数据的工具
- C语言实现简单的日志封装
- C语言中如何实现对超大数据的存取与运算
- 面向对象语言中从数据库中取出数据再封装回对象的方法
- 数据排序的几种方法(c语言实现)
- 制作最小根文件系统
- 分享Java题1
- Ext JS中文乱码解决方案
- 程序员求职之道(《程序员面试笔试宝典》)之求职有用网站及QQ群一览表
- C++ 线程安全的单例模式
- C 语言中实现数据与方法的封装
- Unity3D animation import issue | 模型导入,动画无法播放问题
- Shortest Prefixes
- JAVA中TCP/UDP编程实例
- 内部类
- android中使用SAX解析xml文件
- ISO/IEC 14443----维基百科
- 成功的人生需要准确的定位
- java笔记【十】