to Whanxy
int N; yzhlinux@hotmail.com) * 1.支持字符索引- {7 u. t) A, K, @& W * 2.方便的添加删除修改任意一项0 Z$ ~3 C4 w9 f) p. X7 @3 V * 最后更新 2004-8-9 **1.优化了字符索引的运作方式,使用数组存储5 E) a ?4 C% S3 R7 f **2.重写了底层数据的存储,将连续性的存储方式改为了非连续, *** 从而很好有效地支持了“引用”,并且让数据的删除增加变的更为快速+ m _$ P+ p: o0 u- I& g ///// * 用法句举例1: * YCArray<int,int> test1 ;1 v2 g3 d1 g! J% x2 A* b * test1.Add("Number2",4); * test1.Add("Number1",2);0 N1 ^& D) y1 s: {: V, Z$ M; Z# { * printf("%d %d",test1["Number1"],test1["Number2"]); * 显示: * 2 49 }7 s0 J6 w4 `2 @- x /////8 I3 w+ B& M$ z * 用法句举例2: * YCArray<CString,CString> test2 ; * test2.Add("string2","hahahaha");8 i& L; C7 \! l! N/ |/ g( O * test2.Add("string1","yes yes yes yes");* f; \8 v: |" T. b* l! H# p * printf("%s %s %s",test2["string1"],test2["string2],test2[0]);; G) A. E6 v8 J$ ^) `5 O * 显示: * yes yes yes yes hahahaha yes yes yes yes ///// * 用法句举例3: * YCArray<CString,CString> test3 ;. Y% ?9 c+ w2 Q6 R * test3.Add("string2","hahahaha");' [! g: f4 Y' M* V& B$ e: Z * test3.Add("string1","yes yes yes yes");0 u. ]6 m8 t8 ] * test3.Add("","no no no"); * test3.AddR("string2","yes yes yes yes"); //AddR方法会去搜索字符索引,如果存在则替换 * printf("%s %s %s",test3["string1"],test3["string2],test3[2]);% g0 w: l9 B v/ ` * 显示:" B, \7 R6 X7 A) l' z * yes yes yes yes yes yes yes yes no no no **/: y+ `. d: S# g0 e% K4 d5 E /////////////////////////////////////////////////////////////////////////////: `1 J0 _8 L. `. P& |$ k( d // YCArray<TYPE, ARG_TYPE> #include <afxmt.h>( k" f$ m d* \3 M# [3 u* n* A template<class TYPE, class ARG_TYPE>0 W6 ]0 S8 h* ]" U; U class YCArray : public CObject% }; g* E$ E- W) r( Y" q5 o% v { //friend YCArray<TYPE, ARG_TYPE>; CCriticalSection YCArray_Add;4 u2 A3 x" f# h B7 U+ Q0 C public: // Attributes int GetSize() const; int GetUpperBound() const;0 M* k. q" P0 |* m" I: B' W void SetSize(int nNewSize, int nGrowBy = -1);
0 M+ d3 K8 E4 r& F, { N=StrToInt(Edit1->Text); 4 t+ Y/ i8 t# M. f" x+ J1 t5 K: A int RESULT[N];+ W. g0 l9 ^( B2 Q# c+ E 哈哈,这样的代码很有意思哦.+ ]) v* |( H8 `! [: A2 L 在c++里没有现成的类似vb的redim那样可以自由定义数组边界的办法,很多人提供了一些数组类以实现你这样的需求,同样微软也提供了这样的模板类 CArray ,你可以去参考这个摸板,不过 CArray 写的不够好只能给单线程的地方使用(后来个跟踪进去才发现是它的问题,没把偶气死)并且不能很好的支持使用 & 引用内部的成员(底层机制的问题),我从新改写了它的底层实现,写了一个摸板类,给你用正好满足你的需求.:0 | F! f# v: p" t" U) ]8 n #if !defined(CYCArray_INCLUDED) #define CYCArray_INCLUDED #include "afxtempl.h"0 y' K) s8 C5 o7 h /**3 U1 B2 a- e$ w, K * 动态数组的模板类 (Write By yzhlinux ,you could use it any time any way if you could email me about it// Operations
// Clean up void FreeExtra();+ a/ i2 l9 t/ v* y void RemoveAll();// Accessing elements4 Q* g* ^. l" Z4 B TYPE GetAt(int nIndex) const;
void SetAt(int nIndex, ARG_TYPE newElement); TYPE& ElementAt(int nIndex);TYPE GetAt(CString cIndex) const;1 Q, W" F4 j F void SetAt(CString cIndex, ARG_TYPE newElement);& T9 G1 L$ E" Y% e0 a. ~# v TYPE& ElementAt(CString cIndex);
// Direct Access to the element data (may return NULL)
: {# A" q/ Y" o7 H1 ` const TYPE** GetData() const; TYPE** GetData();// Potentially growing the array2 q0 R! r) P; i, k5 H. p/ }) b* i7 F void SetAtGrow(int nIndex, ARG_TYPE newElement);, ?+ L3 B4 `" E/ \ void SetAtGrow(CString cIndex, ARG_TYPE newElement);
' P) m! d0 R% ]( u; p, i5 m4 D- m; P int Add(ARG_TYPE newElement,CString cIndex = "");7 a, @ g( L- _0 y G int AddR(ARG_TYPE newElement,CString cIndex = "")//如果存在就替换 { int nIndex = GetIndex(cIndex);0 X2 K& F6 z9 q2 ~$ Q' [/ L( L if(cIndex!=""&&nIndex >-1){ operator[](nIndex)=newElement;4 s4 r2 r4 f4 l, V4 v3 a }else{ nIndex = m_nSize;) j. L V9 s0 V$ V' Q SetAtGrow(nIndex, newElement); SETIndex(cIndex,nIndex);- z' H: x" U4 Q7 d2 @' b return nIndex; % k# |6 ~ h5 B P } }0 N* A3 u5 ^5 W3 L+ y6 ~ int AddM(ARG_TYPE newElement,CString cIndex = "")- `% e4 B. ?5 w9 w- P T* M {5 r5 u( ]* c2 v6 }' c static int nIndex ; YCArray_Add.Lock();# g2 Q! h! g/ p nIndex = m_nSize; SetAtGrow(nIndex, newElement);/ \9 L4 I- R6 Q# i! |& c# @: W7 ~ YCArray_Add.Unlock();( c! q" T& h3 k3 _9 m* a: ~ SETIndex(cIndex,nIndex); return nIndex; " z+ X$ R" F1 K- w }; int Append(const YCArray& src);% p9 h. ~1 s6 ]+ T q void Copy(const YCArray& src);// overloaded operator helpers
; {+ _, c# h, v TYPE operator[](int nIndex) const; TYPE& operator[](int nIndex); TYPE operator[](CString cIndex) const; TYPE& operator[](CString cIndex); //YCArray<TYPE,ARG_TYPE> operator=(YCArray<TYPE,ARG_TYPE>& tparr)const; YCArray<TYPE,ARG_TYPE>& operator=(YCArray<TYPE,ARG_TYPE>& tparr);7 j$ |9 T7 t% S/ Y! b4 ?9 t // Operations that move elements around# I% J" E: H: O2 x' n3 w void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1); void RemoveAt(int nIndex, int nCount = 1);# y& U/ } a6 Z2 ^, [: b void RemoveAt(CString cIndex,int nCount = 1); void InsertAt(int nStartIndex, YCArray* pNewArray); void InsertAt(ARG_TYPE newElement,int nIndex,CString cIndex);int GetIndex(CString cIndex);: j1 }8 d" z5 L CString GetIndex(int nIndex);
CString GetSign();
int SetSign(CString& sign);// Implementation' I5 N3 d5 p) i+ X2 d protected:! h D0 m! N4 M TYPE** Ym_pData; // the actual array of data" ^# y6 t/ D/ `) e7 V& C ^& L int m_nSize; // # of elements (upperBound - 1)( q/ G/ s0 `6 K! g' Q" j int m_nMaxSize; // max allocated! j4 Y4 m; M4 P! N$ _4 b int m_nGrowBy; // grow amount
( U- P7 ^; {" }' e8 R7 E% s: D private:1 S6 Z" Y. Q, A( R0 l) e4 Q int lock_sign;8 ]$ e* G& o+ y( e CString Sign; int MAXSIGNTIME;CString* strIndex;
int strIndexNum;# R+ Z( [ a2 m1 j- J BOOL SetIndexSize(int nIndex); BOOL SETIndex(CString cIndex,int nIndex);2 ~; n) }6 y: _/ |$ a/ T0 ^ BOOL INSERTIndex(int nIndex,int nCount =1);# e5 x$ |6 Y l' m BOOL DELIndex(int nIndex,int nCount = 1);7 L6 y( y% h" D5 O# N1 y9 x BOOL DELIndex(CString cIndex,int nCount = 1);2 v& e* r8 B* v( E void DestructAllElement(int nIndex,int nCount) {//销毁对象,包括每个指针指向的对象4 D* W) |( t: ]* z! b DELIndex(nIndex,nCount);# o* W2 T4 T/ l; ]6 x. X ASSERT(nIndex >= 0); ASSERT(nCount >= 0);; J; q {+ v* Z) h+ Y# L& V ASSERT(nIndex + nCount <= m_nSize);" S7 s$ l$ j9 w7 j if(nCount>0&&m_nSize>0){ for(int i =nIndex;i<nIndex+nCount;i++){ //Ym_pData->~TYPE(); // 由于ConstructAllElements 中是 Ym_pData[nIndex] = new TYPE;所以不需要Ym_pData->~TYPE()! r1 b2 L. q1 { {6 ^% M' W delete Ym_pData;5 `4 _8 ?% x4 [, R7 O# f' a }2 ]7 F# D3 a8 B5 R1 s }5 p5 w9 ~5 G0 ]" q9 c3 ? n }; void ConstructAllElements(int nIndex,int nCount)9 a3 Q! t& X% y& Q7 S9 ~4 G; | {//创建对象,包括 new 出每个指针指向的对象- C. J' Q% ]: K! H$ l' J //nIndex = 0;2 W' H4 P5 L0 P0 X memset((void*)(Ym_pData+nIndex), 0, nCount * sizeof(TYPE*)); for (; nCount--; nIndex++) Ym_pData[nIndex] = new TYPE;3 k( s9 T# u3 q" _) \# I }; public:) M1 T, ~; ?5 y3 y, \ // Construction5 G7 R$ a' s0 K6 n YCArray(); YCArray(YCArray<TYPE, ARG_TYPE>& tp);. M; r7 N7 Y @& O7 z$ P0 Q2 F ~YCArray();( G/ A$ T! t: ~- k6 ^( e void Serialize(CArchive&); #ifdef _DEBUG. U0 @, E9 w! V% w/ ?! V, d; A, V void Dump(CDumpContext&) const; void AssertValid() const; #endif};
6 h- o3 [; W/ B//接上面
template<class TYPE, class ARG_TYPE>. O* W) \2 x; c' s! q" } YCArray<TYPE, ARG_TYPE>::~YCArray()0 i; v2 u" ^0 \0 R { ASSERT_VALID(this);
if (Ym_pData != NULL)4 a0 r9 y4 f8 w) G9 R {5 B2 W0 f k4 q0 F+ i DestructAllElement(0,m_nSize);
//DestructElements<TYPE>(Ym_pData, m_nSize); delete[] (BYTE*)Ym_pData; } }/ }) I2 Y: a2 }9 K1 K/ Q4 u template<class TYPE, class ARG_TYPE> CString YCArray<TYPE, ARG_TYPE>::GetSign() {2 Y% {4 n( a- ~/ H lock_sign=0;) `# _/ ?& t0 k2 A F return Sign; S( u& D3 M( @( A }' J0 Z- s4 f f# }/ |( G template<class TYPE, class ARG_TYPE> int YCArray<TYPE, ARG_TYPE>::SetSign(CString& sign) { int i=0; while(lock_sign&&i<MAXSIGNTIME){ Sleep(1); i++;3 s- r# a+ D% p0 V$ h) Z4 q! b9 \/ | }% E7 I% X% |- @ lock_sign=1; Sign=sign; return TRUE;; j" w6 [. q* \% Y } //用与把 nindex 后的索引往后推 nCount ,自动调整好buffer template<class TYPE, class ARG_TYPE>2 @4 p+ E$ N8 }2 d BOOL YCArray<TYPE, ARG_TYPE>::SetIndexSize(int nNewSize) { if(strIndexNum < nNewSize){4 K$ H. `2 ?" [& y, _/ o CString* tp = new CString[nNewSize];//新的buffer for(int i=0;i<strIndexNum;i++){//把老索引复制过来5 m8 h% U/ g2 z9 I P tp = strIndex;5 E' I+ ]7 [0 G }/ M/ E. r( E. _& s7 l for(i=strIndexNum;i<nNewSize;i++){3 x/ F0 J* @8 `6 }2 ?( @ tp = "" ;( y. c [! M- \3 m( k! S } delete[] strIndex ;0 a( \. S3 P! \( m strIndex = tp ;* q& Q' x, S' ^8 { strIndexNum = nNewSize ;- N0 P+ R" R; _; R% K }else if(strIndexNum < nNewSize){ for(int i=nNewSize;i<strIndexNum;i++){ strIndex = "" ;$ A) e/ C9 H& H# U- U# h } } return TRUE; }6 W9 _8 X9 o# |8 O6 l template<class TYPE, class ARG_TYPE> BOOL YCArray<TYPE, ARG_TYPE>::INSERTIndex(int nIndex,int nCount /*=1*/)5 y9 k) ^4 b$ J# ?! k {+ w& N l) v. t, M CString* tp = new CString[m_nSize+nCount];//新的buffer for(int i=0;i<nIndex;i++){//把老索引复制过来 tp = strIndex; }int j =0 ; for(i=nIndex+nCount;i<m_nSize;i++){//把老索引复制过来 tp = strIndex[nIndex+j];: m! ^7 n! ]3 c+ P+ }, Y% v0 A j++; } delete[] strIndex ;' O2 S+ h/ K4 a- w: g strIndex = tp ; return TRUE; }: E8 M$ b) r: l! S) E( Q template<class TYPE, class ARG_TYPE>1 Y$ k; b& _8 i$ B/ n- W; v. P1 y BOOL YCArray<TYPE, ARG_TYPE>::SETIndex(CString cIndex,int nIndex)! w0 m2 m3 t ?- t! ?/ X9 G8 O {//在 nIndex 后面添加一个 字符串索引! ]$ X! Z+ k w6 x5 } strIndex[nIndex] = cIndex ;) t$ K, t4 e N return TRUE; }5 b6 B( |$ h$ ]% n template<class TYPE, class ARG_TYPE>9 O9 g3 V! b( f: A( H# s; w BOOL YCArray<TYPE, ARG_TYPE>:ELIndex(int nIndex,int nCount /*=1*/) {//需要在 m_nSize 变化之前调用!!2 K2 K6 {9 \2 }0 R2 i1 |4 { ASSERT(nIndex >= 0); ASSERT(nCount >= 0); ASSERT(nIndex + nCount <= m_nSize);4 ]6 ^' p* ^* f5 N int j =0 ; for(int i=nIndex+nCount;i<m_nSize;i++){//把老索引复制过来 strIndex[nIndex+j] = strIndex; j++;$ a% ^8 f5 _" e% s } return TRUE; }: U( C% h/ T$ {& P+ Q$ ? template<class TYPE, class ARG_TYPE> BOOL YCArray<TYPE, ARG_TYPE>:ELIndex(CString cIndex,int nCount /*=1*/) { int nIndex=this->GetIndex(cIndex); return this->DELIndex(nIndex,nCount);. Z/ c0 k) T8 w6 f% O } J( H0 g5 m( d1 F1 t template<class TYPE, class ARG_TYPE>+ @: ~3 l$ c* i int YCArray<TYPE, ARG_TYPE>::GetIndex(CString cIndex) {//得到 cIndex 的数字索引 int nPos = -1; for(int i=0;i<m_nSize;i++){& D: s" t' o9 q5 l9 q. A if(strIndex == cIndex){ nPos = i ;break;$ [3 R0 G3 C! |' D0 |3 F } } return nPos;. |# f3 @% T& o0 e7 G }& R1 t! p0 c' u4 x template<class TYPE, class ARG_TYPE> CString YCArray<TYPE, ARG_TYPE>::GetIndex(int nIndex) {//返回 nIndex 的字符串索引 return strIndex[nIndex]; }, r- n0 ^/ o' X- ~; S3 J /////////////////////////////////////////////////////////////////////////////* _9 ]8 z; x P0 {; L' ? // YCArray<TYPE, ARG_TYPE> inline functionstemplate<class TYPE, class ARG_TYPE>
AFX_INLINE int YCArray<TYPE, ARG_TYPE>::GetSize() const) o' g. u& K# \ I6 o) P { return m_nSize; }8 b4 a6 E( Y: F6 w% _ template<class TYPE, class ARG_TYPE> AFX_INLINE int YCArray<TYPE, ARG_TYPE>::GetUpperBound() const { return m_nSize-1; } template<class TYPE, class ARG_TYPE>- B: w7 r/ M4 o0 s9 ` AFX_INLINE void YCArray<TYPE, ARG_TYPE>::RemoveAll() { SetSize(0, -1); } template<class TYPE, class ARG_TYPE>" l6 G: I+ Z$ u) E% c, [ AFX_INLINE TYPE YCArray<TYPE, ARG_TYPE>::GetAt(int nIndex) const { ASSERT(nIndex >= 0 && nIndex < m_nSize); return *Ym_pData[nIndex]; }8 f( Y; ]- b/ h1 E' q% U template<class TYPE, class ARG_TYPE> AFX_INLINE void YCArray<TYPE, ARG_TYPE>::SetAt(int nIndex, ARG_TYPE newElement) { ASSERT(nIndex >= 0 && nIndex < m_nSize); *(Ym_pData[nIndex]) = newElement; }template<class TYPE, class ARG_TYPE>
AFX_INLINE TYPE& YCArray<TYPE, ARG_TYPE>::ElementAt(int nIndex) { ASSERT(nIndex >= 0 && nIndex < m_nSize);' y5 t( N/ e7 ]' G9 C u return *Ym_pData[nIndex]; }template<class TYPE, class ARG_TYPE>
TYPE YCArray<TYPE, ARG_TYPE>::GetAt(CString cIndex) const {8 o# ?+ |3 \( }. [, J+ Z. j( z, | int nIndex=GetIndex(cIndex);. O- A3 T( e+ n- x% M; a; \ return GetAt(nIndex); } template<class TYPE, class ARG_TYPE>0 e+ c$ X: P8 U1 U3 s7 a: f& _+ H void YCArray<TYPE, ARG_TYPE>::SetAt(CString cIndex, ARG_TYPE newElement)$ n8 i; N9 c* W- S+ X { int nIndex=GetIndex(cIndex);& `& ^$ a2 c# a: H9 c return SetAt(nIndex, newElement);0 L- L2 k0 m U6 x4 J6 A" q/ A9 ` } template<class TYPE, class ARG_TYPE>5 G' p2 Y6 ?4 T: w TYPE& YCArray<TYPE, ARG_TYPE>::ElementAt(CString cIndex) { int nIndex=GetIndex(cIndex);0 Z2 c& Z, ?: R" A* p8 T. R: {0 l- h return ElementAt(nIndex);" c. R$ h% R, _ K }) p/ x8 |3 Z" B- ]% A) u template<class TYPE, class ARG_TYPE> AFX_INLINE const TYPE** YCArray<TYPE, ARG_TYPE>::GetData() const { return (const TYPE**)Ym_pData; } template<class TYPE, class ARG_TYPE> AFX_INLINE TYPE** YCArray<TYPE, ARG_TYPE>::GetData()/ l. O7 ^+ j& c- x0 Z { return (TYPE**)Ym_pData; } template<class TYPE, class ARG_TYPE> AFX_INLINE int YCArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement,CString cIndex /* ="" */)4 o; Z: F# P/ v/ r# k. A( E+ N8 Y& R { int nIndex = m_nSize; SetAtGrow(nIndex, newElement);" k- Y8 D" W: z5 }$ p4 ~ SETIndex(cIndex,nIndex); return nIndex; }/ R% q) f4 K+ u8 U. V. [) p3 J template<class TYPE, class ARG_TYPE>& w0 i, k4 ?8 C3 e AFX_INLINE TYPE YCArray<TYPE, ARG_TYPE>:perator[](int nIndex) const { return GetAt(nIndex); } template<class TYPE, class ARG_TYPE> AFX_INLINE TYPE& YCArray<TYPE, ARG_TYPE>:perator[](int nIndex) { return ElementAt(nIndex); }3 ^0 E/ n; P3 G0 C+ { F template<class TYPE, class ARG_TYPE> C' c3 [3 f1 y* ` AFX_INLINE TYPE YCArray<TYPE, ARG_TYPE>:perator[](CString cIndex) const {5 V# m% i2 w# c1 ^- r. O# N int nIndex=GetIndex(cIndex);return operator[](nIndex);" L1 U% A! F, B X7 ]0 t }' z! [2 r; c* t' H9 L6 L template<class TYPE, class ARG_TYPE>$ u/ A6 O' E4 f; [! y AFX_INLINE TYPE& YCArray<TYPE, ARG_TYPE>:perator[](CString cIndex)
{ n3 u- Y6 {2 `1 z+ B( t& A int nIndex=GetIndex(cIndex);6 l: d. ~( c* @* S return operator[](nIndex); }' j: t$ }* G# D& D /*+ X' x* |0 z7 |/ r template<class TYPE, class ARG_TYPE># P& h4 v w# L, X AFX_INLINE YCArray<TYPE,ARG_TYPE> YCArray<TYPE, ARG_TYPE>:perator=(YCArray<TYPE,ARG_TYPE>& tparr) const {) N* X% g+ L6 F' p4 c int i,j;2 O5 s" _9 L) t( U: h/ [ for(i=0;i<tparr.GetSize();i++){: D5 f+ W1 o! R: U$ {. D( D8 C j = GetIndex(tparr.GetIndex(i)); if(j>-1){; f; q+ [" q8 f+ h operator[](tparr.GetIndex(i)) = tparr;$ o6 H7 ~/ a8 j }else{ Add(tparr,tparr.GetIndex(i)); }0 g8 i' ^! L( J% G+ O8 k } return this;4 W* T; T4 B P- v* g- l }: ~' N$ w$ N. `5 ^- v. S3 _3 q */ template<class TYPE, class ARG_TYPE>! L" v7 N* v8 J! S2 f' |) f( d AFX_INLINE YCArray<TYPE,ARG_TYPE>& YCArray<TYPE, ARG_TYPE>:perator=(YCArray<TYPE,ARG_TYPE>& src) { ASSERT_VALID(this);! b0 e( C# P" N9 ` ASSERT(this != &src); // cannot append to itselfSetSize(src.m_nSize);0 l- P! g5 @, F" {# V! ]! K for(int i=0;i<m_nSize;i++){+ @: W: g, q9 | J2 v$ {, y /*将此句修改为内存拷贝*///0 k2 w+ `5 x" W. [9 P' C8 h$ U *Ym_pData = *src.Ym_pData ;; F( M5 }% P' @' U* Z //memcpy(Ym_pData,src.Ym_pData,sizeof(TYPE));
SETIndex(src.GetIndex(i),i);" x6 W# g8 B. E; p4 L- p5 v }9 [1 M& }. m* e; }4 ?. b" z return *this; }4 n. @" X) X" ~( ~: e ///////////////////////////////////////////////////////////////////////////// // YCArray<TYPE, ARG_TYPE> out-of-line functionstemplate<class TYPE, class ARG_TYPE>. U0 W; D+ I" a$ Z, L$ p2 Q, i YCArray<TYPE, ARG_TYPE>::YCArray()0 a; m( n- \5 b) S# X" u {
Ym_pData = NULL; strIndexNum = m_nSize = m_nMaxSize = m_nGrowBy = 0; strIndex=NULL;MAXSIGNTIME=10; } template<class TYPE, class ARG_TYPE> YCArray<TYPE, ARG_TYPE>::YCArray(YCArray<TYPE, ARG_TYPE>& tp); }8 z) d0 U' |. a: S { Ym_pData = NULL;- S: K: x6 f3 z) I4 ?, g. `2 S strIndexNum = m_nSize = m_nMaxSize = m_nGrowBy = 0;& g/ I. n( o4 y$ p6 L) V6 q9 G7 e strIndex=NULL;MAXSIGNTIME=10; operator=(tp);# f B! K) B9 k( K0 c }template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::SetSize(int nNewSize, int nGrowBy) {, x& P+ Y% c4 X ASSERT_VALID(this);7 ~- T3 D5 `1 n5 C6 y ASSERT(nNewSize >= 0);if (nGrowBy != -1)
m_nGrowBy = nGrowBy; // set new sizeif (nNewSize == 0){0 X# g- J6 R5 [& _1 h* o // shrink to nothing4 I6 r6 Z& |4 S/ O3 @ if (Ym_pData != NULL){. ]: f6 T/ y8 \0 A DestructAllElement(0,m_nSize);! d4 b6 q9 X2 K* ^/ h' O //DestructElements<TYPE>(Ym_pData, m_nSize);
delete[] (BYTE*)Ym_pData; Ym_pData = NULL; } m_nSize = m_nMaxSize = 0; } else if (Ym_pData == NULL){# o0 l; _3 B) v! s4 g* v // create one with exact size #ifdef SIZE_T_MAX# [. Z% S) L0 n9 S ASSERT(nNewSize <= SIZE_T_MAX/sizeof(TYPE*)); // no overflow5 s- Y7 T' e/ E$ Y& z" u #endif Ym_pData = (TYPE**) new BYTE[nNewSize * sizeof(TYPE*)];/ b& ] }' v% R3 P1 |* a ConstructAllElements(0,nNewSize);//ConstructElements<TYPE>(Ym_pData, nNewSize);8 {7 v0 ^/ r% ]% ^) F; r m_nSize = m_nMaxSize = nNewSize;/ }4 W: W2 Z- [2 P& J$ U; h. u } else if (nNewSize <= m_nMaxSize){7 r' p! T, g6 g+ a // it fits if (nNewSize > m_nSize) { // initialize the new elements; m1 E* } L4 q B/ X6 z8 ` ConstructAllElements(m_nSize,nNewSize-m_nSize);//ConstructElements<TYPE>(&Ym_pData[m_nSize], nNewSize-m_nSize); }$ O: K* l! K7 W( Z5 a4 h else if (m_nSize > nNewSize) { // destroy the old elements# f* q! H0 p% J DestructAllElement(nNewSize,m_nSize-nNewSize); //DestructElements<TYPE>(&Ym_pData[nNewSize], m_nSize-nNewSize); } m_nSize = nNewSize; }# ?7 W6 `" U+ r. i9 P) X else { // otherwise, grow array int nGrowBy = m_nGrowBy;! f {( W' D( L' C& ] if (nGrowBy == 0)6 [' ^! S6 M, p0 ~5 d { // heuristically determine growth when nGrowBy == 0( B4 h6 Z9 B m, v( @7 b // (this avoids heap fragmentation in many situations) nGrowBy = m_nSize / 8;" g1 M# \! @. C7 q; X- L4 |- ^ nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);) V! p0 Y- |1 }) N7 L! j% l/ H* ? } int nNewMax; if (nNewSize < m_nMaxSize + nGrowBy): e# p6 r- {- }$ ^ G7 T/ F6 M nNewMax = m_nMaxSize + nGrowBy; // granularity1 z0 S% ]( l8 W6 `8 }. @! N else* j% h& A K% [4 u2 f5 C2 \ nNewMax = nNewSize; // no slushASSERT(nNewMax >= m_nMaxSize); // no wrap around* ~, D/ D- _! W3 G& u4 E #ifdef SIZE_T_MAX
ASSERT(nNewMax <= SIZE_T_MAX/sizeof(TYPE)); // no overflow #endif4 e9 S3 H0 N4 |; u# _& z4 Z TYPE** pNewData = (TYPE**) new BYTE[nNewMax * sizeof(TYPE*)];//TYPE* pNewData = (TYPE*) new BYTE[nNewMax * sizeof(TYPE)];// copy new data from old, Z3 \$ x' i: l$ p memcpy(pNewData, Ym_pData, m_nSize * sizeof(TYPE*));
// construct remaining elements" ^# ]# D1 k6 @ ASSERT(nNewSize > m_nSize); //throw("/*wait for me --- yzhlinux*/");5 ^' x3 _% ^/ f" I delete[] (BYTE*)Ym_pData;
Ym_pData = pNewData; ConstructAllElements(m_nSize,nNewSize-m_nSize);//ConstructElements<TYPE>(&pNewData[m_nSize], nNewSize-m_nSize);// get rid of old stuff (note: no destructors called)- `. g, T: W. P+ V) R0 `1 j m_nSize = nNewSize;
m_nMaxSize = nNewMax; } SetIndexSize(nNewSize);5 j. B. x. c$ ?$ B }//接上面
template<class TYPE, class ARG_TYPE>8 Z) }% G2 K: X6 W5 _ int YCArray<TYPE, ARG_TYPE>::Append(const YCArray& src)& R; g+ T+ p4 b2 I: x { ASSERT_VALID(this);/ }5 \! y% c' F1 o! P. b ASSERT(this != &src); // cannot append to itself
int nOldSize = m_nSize;9 {# g8 B; v* O) r: j* F% H) p( @ SetSize(m_nSize + src.m_nSize);
ConstructAllElements(nOldSize,src.m_nSize);
for(int i=nOldSize;i<m_nSize;i++){ /*将此句修改为内存拷贝*/// *Ym_pData = *src.Ym_pData[i-nOldSize] ; //memcpy(Ym_pData,src.Ym_pData[i-nOldSize],sizeof(TYPE));6 k/ }9 i9 q4 O: P; }) U SETIndex(src.GetIndex(i-nOldSize),i);( \& Q s0 g4 t; s2 b }2 V6 C) V+ w4 M: K: o /*wait for me*///CopyElements<TYPE>(Ym_pData + nOldSize, src.Ym_pData, src.m_nSize);* e( k# T: Y7 A% z4 z return nOldSize;1 r& D, o1 Z z }template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::Copy(const YCArray& src): K4 E' m' I$ I5 D5 ~6 G { ASSERT_VALID(this); ASSERT(this != &src); // cannot append to itselfSetSize(src.m_nSize);
for(int i=0;i<m_nSize;i++){: N2 ^ g4 p6 p' G# J! ^ /*将此句修改为内存拷贝*///*Ym_pData = *src.Ym_pData ; memcpy(Ym_pData,src.Ym_pData,sizeof(TYPE)); SETIndex(src.GetIndex(i),i);* G- V) X6 W; X }( @; k, I! p% Q5 W8 H! W- U /*wait for me*///CopyElements<TYPE>(Ym_pData, src.Ym_pData, src.m_nSize); n( ~% d% ?( N# w }template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::FreeExtra()# n: m, ^4 Y/ T8 |' l6 K. m { ASSERT_VALID(this);if (m_nSize != m_nMaxSize) I( D' e- Y0 j0 M$ } {
// shrink to desired size7 F, M2 O8 {, Y# y4 s #ifdef SIZE_T_MAX& I2 o" S4 A) s: }4 q9 ^ ASSERT(m_nSize <= SIZE_T_MAX/sizeof(TYPE)); // no overflow #endif TYPE* pNewData = NULL; if (m_nSize != 0)4 a3 t5 ~0 [ M' y1 y, c5 v5 F { pNewData = (TYPE**) new BYTE[m_nSize * sizeof(TYPE*)];1 o5 W) W# {. |, f2 W // copy new data from old' u2 n' |2 \' v! I$ o memcpy(pNewData, Ym_pData, m_nSize * sizeof(TYPE*));( F9 J- h) j6 U }// get rid of old stuff (note: no destructors called)- M g+ g# N4 }! f delete[] (BYTE*)Ym_pData;
Ym_pData = pNewData; m_nMaxSize = m_nSize; }% b" k& e d& Q6 |) y } template<class TYPE, class ARG_TYPE>8 i1 ]4 ^* r w+ @7 i void YCArray<TYPE, ARG_TYPE>::SetAtGrow(CString cIndex, ARG_TYPE newElement)# ^ `0 g6 n* |3 E- F9 F; i' t3 R { int nIndex=GetIndex(cIndex);; P4 Q' o& J( n. ~ return SetAtGrow(nIndex,newElement); } template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement)" h8 Y# g$ X& u; T; b7 c {$ r: w9 [* h: h" q+ _, ~) U ASSERT_VALID(this);0 i/ A9 s% j: W ASSERT(nIndex >= 0);if (nIndex >= m_nSize)3 o9 N6 g0 R K; H" j SetSize(nIndex+1, -1);
*Ym_pData[nIndex] = newElement;5 H8 X, C! N& l( N. c2 |- X }template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount /*=1*/)5 {8 v$ M8 ?1 m5 Z- i; p { ASSERT_VALID(this);. P" l" D S Y$ a9 h- e9 K+ e ASSERT(nIndex >= 0); // will expand to meet need7 m8 b+ k( Z+ y4 w& Z! w ASSERT(nCount > 0); // zero or negative size not allowedif (nIndex >= m_nSize)
{ // adding after the end of the array) z% H0 q2 a7 ?. G* } SetSize(nIndex + nCount, -1); // grow so nIndex is valid0 W2 d( a+ @# l- @1 k } else$ P$ }+ b4 n( W M2 N {( C4 K1 x8 @ b9 }* |6 F // inserting in the middle of the array int nOldSize = m_nSize; SetSize(m_nSize + nCount, -1); // grow it to new size // destroy intial data before copying over it* ~' c& Y9 ]# J' j$ X /*不需要销毁了,因为 SetSize 的是指针*///DestructAllElement(nOldSize,nCount); //DestructElements<TYPE>(&Ym_pData[nOldSize], nCount);& s& `/ ^( Q! y# W' S // shift old data up to fill gap memmove(&Ym_pData[nIndex+nCount], &Ym_pData[nIndex], (nOldSize-nIndex) * sizeof(TYPE*));// re-init slots we copied from6 ^# l" |3 C% ?' [! X /*不需要销毁了,因为 SetSize 的是指针*///ConstructAllElements(nIndex,nCount);//ConstructElements<TYPE>(&Ym_pData[nIndex], nCount);5 |' I8 n. u' e4 X4 r8 J }
// insert new value in the gap
ASSERT(nIndex + nCount <= m_nSize); while (nCount--){4 f% h& w5 X/ M5 N9 i5 E4 Q *Ym_pData[nIndex++] = newElement;- w4 g0 z4 {$ G" t+ S: }# u } } template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::RemoveAt(CString cIndex,int nCount /*=1*/)7 z" a0 t4 G4 O" C3 M ?: I2 |( B {3 `" V2 B6 e" V; L int nIndex = GetIndex(cIndex); RemoveAt(nIndex,nCount); } template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::RemoveAt(int nIndex, int nCount /*=1*//*=1*/)0 K* T) S# i5 R {9 R! y3 i, \: e$ Q# m ASSERT_VALID(this); ASSERT(nIndex >= 0); ASSERT(nCount >= 0);% I* `( d+ a# Z2 K# v/ J6 ? ASSERT(nIndex + nCount <= m_nSize); //yzh DELIndex(nIndex);$ @4 N; \3 P5 _6 h: w$ B //yzh- J1 |5 p' |( [ // just remove a range5 D0 X3 M8 ~9 H+ ? int nMoveCount = m_nSize - (nIndex + nCount); //需要移动的数目 DestructAllElement(nIndex,nCount); //DestructElements<TYPE>(&Ym_pData[nIndex], nCount); if (nMoveCount) memmove(&Ym_pData[nIndex], &Ym_pData[nIndex + nCount], nMoveCount * sizeof(TYPE*));' E* G8 m$ {) n6 o, U- \+ L m_nSize -= nCount;$ `; z( p9 G2 n" i- c7 v; ^5 m }template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::InsertAt(int nStartIndex, YCArray* pNewArray)$ r) t" T4 F5 B7 M9 t1 l. w { ASSERT_VALID(this); ASSERT(pNewArray != NULL);: E& [* J* s; P0 C6 [ ASSERT_VALID(pNewArray);" I& i. z2 m+ d, B ASSERT(nStartIndex >= 0);if (pNewArray->GetSize() > 0)3 K/ e% n0 T. G% x {/ u- m* V0 ]+ Z. E" q InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());; [. b$ j/ n, a4 o7 ^ for (int i = 0; i < pNewArray->GetSize(); i++)- I( @! m6 W4 \ P SetAt(nStartIndex + i, pNewArray->GetAt(i));
}8 V. c/ x1 Q. ]; H } template<class TYPE, class ARG_TYPE> a$ y6 a& p$ `, i, I) ]! i5 t7 J" ` void YCArray<TYPE, ARG_TYPE>::InsertAt(ARG_TYPE newElement, int nIndex,CString cIndex) {3 w _, ]" w d7 b. A$ i6 k( W( k D ADDIndex(cIndex,nIndex+1);9 }; v h" G9 h( F InsertAt(newElement,nIndex); } template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::Serialize(CArchive& ar) {4 c }/ Q# u7 T ASSERT_VALID(this);7 {2 A3 X; f D throw("/*wait for me --- yzhlinux*/"); CObject::Serialize(ar); if (ar.IsStoring()) { ar.WriteCount(m_nSize); }+ E& z$ k( {& y else {; ]! Q# S1 d! t, P DWORD nOldSize = ar.ReadCount(); SetSize(nOldSize, -1);$ N W8 a6 r+ F# b# g }" S- T3 K! n& m9 a //SerializeElements<TYPE>(ar, Ym_pData, m_nSize); }#ifdef _DEBUG
template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::AssertValid() const { CObject::AssertValid();if (Ym_pData == NULL); y7 z* } q$ K5 t0 M! Z- R% c {
ASSERT(m_nSize == 0);7 C( j2 l5 V" Y1 N ASSERT(m_nMaxSize == 0);0 H+ I- v% _! Y# ] }: `3 n$ V Q' n2 x9 _5 ?/ V' K else { ASSERT(m_nSize >= 0); ASSERT(m_nMaxSize >= 0);# ?; h0 }9 y" f7 j% g5 d- P ASSERT(m_nSize <= m_nMaxSize); ASSERT(AfxIsValidAddress(Ym_pData, m_nMaxSize * sizeof(TYPE*))); }4 }2 H9 ~6 z3 V } template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>:ump(CDumpContext& dc) const, o9 z0 U( H- [# W$ P+ t5 D) n( ]! t { CObject:ump(dc); throw("/*wait for me --- yzhlinux*/"); I9 {' D: y! M b dc << "with " << m_nSize << " elements"; if (dc.GetDepth() > 0): D) P, }) C9 b" D4 w {9 b) I" z& u% F/ V& D# k dc << "\n";1 m9 _. z( V g3 I; t! p# J# p /*wait for me --- yzhlinux*/// DumpElements<TYPE>(dc, Ym_pData, m_nSize);, Y" L! h! y: P# x6 b }dc << "\n";; S% N A- X8 s" w4 { }& Z" j& b* @* }- J, Y1 v: t9 R #endif
#endif
//完
欢迎光临 下沙论坛 (http://bbs.xiasha.cn/) | Powered by Discuz! X3.3 |