zoukankan      html  css  js  c++  java
  • 类似vector的ProArray封装类CProArray

      在做ProE二次开发的时候,时常会用到数组ProArray,虽然掌握之后并不难,但是用法毕竟不简洁,有时候难免出错,比如用ProArrayAlloc申请了一数组,但忘了释放,这就会导致内存泄露,等等。

      我们知道,C++的标准库STL中有vector,完全可以替代C中难用的原生数组,所以我想,可不可以写一个类似vector的类来封装ProArray呢?

    经过一段时间的编码,终于完成了这个类似vector的CProArray类,代码如下:

    CProArray.h

      1 #ifndef _C_PRO_ARRAY_H_
      2 #define _C_PRO_ARRAY_H_
      3 
      4 #include <ProToolkit.h>
      5 #include <ProArray.h>
      6 #include <exception>
      7 #include <stdexcept>
      8 
      9 using std::exception;
     10 using std::out_of_range;
     11 using std::bad_alloc;
     12 
     13 template<class TYPE, size_t reallocationSize>
     14 class CProList;
     15 
     16 template<class TYPE, size_t reallocationSize = 5>
     17 class CProArray
     18 {
     19     friend class CProList<TYPE, reallocationSize>;
     20 
     21 public:
     22     CProArray() 
     23         //throw(bad_alloc)
     24         : m_arr(NULL), m_nCntAdd(reallocationSize), use(1)
     25     {
     26         if (reallocationSize == 0)  m_nCntAdd = 5;
     27         if (PRO_TK_OUT_OF_MEMORY == ProArrayAlloc(0, sizeof(TYPE), m_nCntAdd, &m_arr))
     28             throw bad_alloc("out of memory.");
     29     }
     30 
     31     ~CProArray()
     32     {
     33         ProArrayFree(&m_arr);
     34     }
     35 
     36     CProArray(const CProArray& arrSrc) 
     37         //throw(bad_alloc)
     38         : m_arr(NULL), m_nCntAdd(reallocationSize), use(1)
     39     {
     40         if (reallocationSize == 0)    m_nCntAdd = 5;
     41         if (PRO_TK_OUT_OF_MEMORY == ProArrayAlloc(0, sizeof(TYPE), m_nCntAdd, &m_arr))
     42             throw bad_alloc("out of memory.");
     43         size_t nSizeSrc = arrSrc.size();
     44         if (0 != nSizeSrc)
     45         {
     46             if (PRO_TK_OUT_OF_MEMORY == ProArrayObjectAdd(&m_arr, -1, nSizeSrc, arrSrc.m_arr))
     47                 throw bad_alloc("out of memory.");
     48         }
     49     }
     50 
     51     CProArray& operator=(const CProArray& arrSrc) 
     52         //throw(bad_alloc)
     53     {
     54         clear();
     55         size_t nSizeSrc = arrSrc.size();
     56         if (0 != nSizeSrc)
     57         {
     58             if (PRO_TK_OUT_OF_MEMORY == ProArrayObjectAdd(&m_arr, -1, nSizeSrc, arrSrc.m_arr))
     59                 throw bad_alloc("out of memory.");
     60         }
     61     }
     62 
     63 public:
     64     size_t size() const
     65     {
     66         int nSize;
     67         ProArraySizeGet(m_arr, &nSize);
     68         return nSize;
     69     }
     70 
     71     bool is_empty() const
     72     {
     73         return !size();
     74     }
     75 
     76     void clear()
     77     {
     78         if (0 != size())
     79             ProArrayObjectRemove(&m_arr, 0, size());
     80     }
     81 
     82     void push_back(const TYPE& val) 
     83         //throw(bad_alloc)
     84     {
     85         if (PRO_TK_OUT_OF_MEMORY == ProArrayObjectAdd(&m_arr, -1, 1, (void*)(&val)))
     86             throw bad_alloc("out of memory.");
     87     }
     88 
     89     void pop_back()
     90     {
     91         if (!is_empty())
     92             ProArrayObjectRemove(&m_arr, -1, 1);
     93     }
     94 
     95     const TYPE& front() const 
     96         //throw(out_of_range)
     97     {
     98         if (is_empty())
     99             throw out_of_range("empty CProArray.");
    100         return reinterpret_cast<const TYPE*>(m_arr)[0];
    101     }
    102 
    103     TYPE& front() 
    104         //throw(out_of_range)
    105     {
    106         return const_cast<TYPE&>(const_cast<const CProArray*>(this)->front());
    107     }
    108 
    109     const TYPE& back() const 
    110         //throw(out_of_range)
    111     {
    112         if (is_empty())
    113             throw out_of_range("empty CProArray.");
    114         return  reinterpret_cast<const TYPE*>(m_arr)[size()-1];
    115     }
    116 
    117     TYPE& back() 
    118         //throw(out_of_range)
    119     {
    120         return const_cast<TYPE&>(const_cast<const CProArray*>(this)->back());
    121     }
    122 
    123     const TYPE& operator[](size_t index) const 
    124         //throw(out_of_range)
    125     {
    126         if (is_empty())
    127             throw out_of_range("empty CProArray.");
    128         if (size() <= index)
    129             throw out_of_range("invalid index of CProArray.");
    130         return reinterpret_cast<const TYPE*>(m_arr)[index];
    131     }
    132 
    133     TYPE& operator[](size_t index) 
    134         //throw(out_of_range)
    135     {
    136         return const_cast<TYPE&>(const_cast<const CProArray*>(this)->operator[](index));
    137     }
    138 
    139     const TYPE& at(size_t index) const 
    140         //throw(out_of_range)
    141     {
    142         if (is_empty())
    143             throw out_of_range("empty CProArray.");
    144         if (size() <= index)
    145             throw out_of_range("invalid index of CProArray.");
    146         return reinterpret_cast<const TYPE*>(m_arr)[index];
    147     }
    148 
    149     TYPE& at(size_t index) 
    150         //throw(out_of_range)
    151     {
    152         return const_cast<TYPE&>(const_cast<const CProArray*>(this)->at(index));
    153     }
    154 
    155     void insert_at(size_t index, const TYPE& val) 
    156         //throw(out_of_range, bad_alloc)
    157     {
    158         if (size() < index)
    159             throw out_of_range("invalid index of CProArray.");
    160         if (size() == index)
    161             index = -1;
    162         if (PRO_TK_OUT_OF_MEMORY == ProArrayObjectAdd(&m_arr, index, 1, (void*)(&val)))
    163             throw bad_alloc("out of memory.");
    164     }
    165 
    166     void insert_at(size_t index, size_t cnt, const TYPE *pVal) 
    167         //throw(out_of_range, bad_alloc)
    168     {
    169         if (size() < index)
    170             throw out_of_range("invalid index of CProArray.");
    171         if (size() == index) 
    172             index = -1;
    173         if (PRO_TK_OUT_OF_MEMORY == ProArrayObjectAdd(&m_arr, index, cnt, (void*)pVal))
    174             throw bad_alloc("out of memory.");
    175     }
    176 
    177     void remove_at(size_t index, size_t cnt = 1) 
    178         //throw(out_of_range)
    179     {
    180         if (size() <= index)
    181             throw out_of_range("invalid index of CProArray.");
    182         if (size() - index < cnt)
    183             throw out_of_range("count to remove is out of range.");
    184         ProArrayObjectRemove(&m_arr, index, cnt);
    185     }
    186 
    187     operator ProArray() const
    188     {
    189         return m_arr; 
    190     }
    191 
    192 public:
    193     ProArray m_arr;
    194 private:
    195     int m_nCntAdd;
    196     size_t use;
    197 };
    198 
    199 #endif

    代码说明:

    1、该类代码经过我反复测试,应该不存在Bug。

    2、该类的方法名完全参考vector类的方法名,内部全部是用ProArray的原生方法实现的。

    3、在构造函数中通过ProArrayAlloc申请了内存,在析构函数中通过ProArrayFree释放了内存,所以避免了内存泄露。

    4、该类有属性为public的ProArray成员m_arr,如果在某些代码处,需要通过ProArray原生方法操作数组,直接获取该成员即可。

    5、该类在使用过程中,若出现访问越界等错误,会抛出异常。

    6、该类使用C++的模板元编程实现。

    7、由于每个方法代码都很短,所以全部写在头文件中,即全部为内联函数。

    使用Demo:

    CProArray<int> nArr;
    nArr.push_back(6);
    nArr.push_back(7);
    for (int i=0; i<nArr.size(); ++i)
    {
    	CString cstr;
    	cstr.Format(TEXT("%d"), nArr[i]);
    	AfxMessageBox(cstr);
    }
  • 相关阅读:
    关联规则算法---Eclat算法
    Apriori算法第二篇----详细分析和代码实现
    scrapy框架初识
    git入门
    phantomjs的和谷歌浏览器的简单使用
    selenium模块的而简单使用
    代理ip的使用以及多进程爬取
    爬虫之re块解析
    爬虫初识和request使用
    xpath的基础使用
  • 原文地址:https://www.cnblogs.com/Hisin/p/2613341.html
Copyright © 2011-2022 走看看