您的位置:首页 > 编程语言 > C语言/C++

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

2013-10-20 21:18 507 查看
  出处:http://blog.csdn.net/justme0/article/details/10055441

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

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

1. vector 的接口

[cpp] view
plaincopyprint?

/******************************************************************** 

    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 的实现

[cpp] view
plaincopyprint?

/******************************************************************** 

    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. 测试程序

[cpp] view
plaincopyprint?

/******************************************************************** 

    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. 运行结果

[plain] view
plaincopyprint?

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 形式”。桑心啊,我只好贴在这独自欣赏了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  CC++