现在的位置: 首页 > 综合 > 正文

类似vector的ProArray封装类CProArray

2012年10月23日 ⁄ 综合 ⁄ 共 4821字 ⁄ 字号 评论关闭

  在做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);
}

 

抱歉!评论已关闭.