在做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);
}
原文链接: https://www.cnblogs.com/Hisin/archive/2012/07/28/2613341.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/57095
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!