to Whanxy
int N; yzhlinux@hotmail.com) * 1.支持字符索引" c( q: k9 M9 O * 2.方便的添加删除修改任意一项; `) Z; N B, i' @ * 最后更新 2004-8-9 **1.优化了字符索引的运作方式,使用数组存储 **2.重写了底层数据的存储,将连续性的存储方式改为了非连续,; |4 I+ G' v8 G' R- k' x *** 从而很好有效地支持了“引用”,并且让数据的删除增加变的更为快速 /////7 k- T) X. H' H7 Y T% } * 用法句举例1: * YCArray<int,int> test1 ; * test1.Add("Number2",4);$ a- `* I$ T; ?* p * test1.Add("Number1",2);; ]( L: C2 _+ U7 t `2 K * printf("%d %d",test1["Number1"],test1["Number2"]);8 V g% d! N5 k$ H1 {7 y- j * 显示: * 2 4) ^' h+ P; x' i+ {# X/ S+ } ///// * 用法句举例2: * YCArray<CString,CString> test2 ; * test2.Add("string2","hahahaha"); * test2.Add("string1","yes yes yes yes"); * printf("%s %s %s",test2["string1"],test2["string2],test2[0]);/ P4 \, c/ Z8 v6 O6 a * 显示:4 ?. S8 e0 a3 `+ s* k* M: Q" Q * yes yes yes yes hahahaha yes yes yes yes ///// * 用法句举例3:( A6 P. Q! Z9 h$ d/ e * YCArray<CString,CString> test3 ;. k9 v' N6 G8 {+ E& t * test3.Add("string2","hahahaha"); * test3.Add("string1","yes yes yes yes"); * test3.Add("","no no no"); * test3.AddR("string2","yes yes yes yes"); //AddR方法会去搜索字符索引,如果存在则替换 * printf("%s %s %s",test3["string1"],test3["string2],test3[2]); * 显示:9 k) a, H% t# V * yes yes yes yes yes yes yes yes no no no **/% \, E5 N7 C `" d& Z0 g5 \ /////////////////////////////////////////////////////////////////////////////: P7 v. ^! X3 e; v9 a. b // YCArray<TYPE, ARG_TYPE> #include <afxmt.h>0 ?* D6 W: M6 u" ^3 a* S/ d template<class TYPE, class ARG_TYPE> class YCArray : public CObject7 ]1 {4 c6 q" N2 h { //friend YCArray<TYPE, ARG_TYPE>;7 m, l/ ?2 D1 k7 X CCriticalSection YCArray_Add;/ `5 t' _1 [4 N" J' T$ B public:$ q; b$ g# B0 i2 |/ [ // Attributes int GetSize() const;; J) w* q8 I5 f1 w( n' d; N int GetUpperBound() const;' ~; v8 T' n8 G5 s6 Y4 g void SetSize(int nNewSize, int nGrowBy = -1);
N=StrToInt(Edit1->Text); int RESULT[N];1 L* j$ d; W- c4 { 哈哈,这样的代码很有意思哦. 在c++里没有现成的类似vb的redim那样可以自由定义数组边界的办法,很多人提供了一些数组类以实现你这样的需求,同样微软也提供了这样的模板类 CArray ,你可以去参考这个摸板,不过 CArray 写的不够好只能给单线程的地方使用(后来个跟踪进去才发现是它的问题,没把偶气死)并且不能很好的支持使用 & 引用内部的成员(底层机制的问题),我从新改写了它的底层实现,写了一个摸板类,给你用正好满足你的需求.:, [+ P2 |* |6 ^! c7 q! C3 U #if !defined(CYCArray_INCLUDED) #define CYCArray_INCLUDED* t H- }7 a' \; Q #include "afxtempl.h" /**" {2 X0 q2 O; f% ]8 S * 动态数组的模板类 (Write By yzhlinux ,you could use it any time any way if you could email me about it// Operations
// Clean up void FreeExtra(); void RemoveAll();// Accessing elements
TYPE GetAt(int nIndex) const; void SetAt(int nIndex, ARG_TYPE newElement);2 S+ x) Y% y U1 V Z( m TYPE& ElementAt(int nIndex);TYPE GetAt(CString cIndex) const;8 }2 [$ t: E2 `* j N6 B+ V% _- I void SetAt(CString cIndex, ARG_TYPE newElement);4 n( r- Y X( X! t/ p TYPE& ElementAt(CString cIndex);
& ~$ k! n& P2 ?* Z// Direct Access to the element data (may return NULL)7 W7 |% j e: Z" F! O8 e! ] const TYPE** GetData() const;
" K* c3 J n- D( T TYPE** GetData();// Potentially growing the array
3 M/ R, L. P" B$ |. a! Y void SetAtGrow(int nIndex, ARG_TYPE newElement);' d& B9 M/ w* [, M9 Z void SetAtGrow(CString cIndex, ARG_TYPE newElement);7 i8 K2 c- e0 e+ C0 u int Add(ARG_TYPE newElement,CString cIndex = ""); int AddR(ARG_TYPE newElement,CString cIndex = "")//如果存在就替换0 b* z, V* z5 s- u/ X { int nIndex = GetIndex(cIndex);+ _- J) v* S# D if(cIndex!=""&&nIndex >-1){3 U3 }/ Q K9 X& l3 g; ^! N+ u' M4 A operator[](nIndex)=newElement;/ ~. O! s. K. u6 ^; x }else{+ N1 A& v. x% v y# r& V nIndex = m_nSize;* d6 ?2 d# a0 n4 M% E; s SetAtGrow(nIndex, newElement);& M. @1 Z4 C0 r# X9 |" M6 k SETIndex(cIndex,nIndex); return nIndex; } }1 f4 a' w2 J1 f* p5 k2 G int AddM(ARG_TYPE newElement,CString cIndex = "") { static int nIndex ; YCArray_Add.Lock();4 o8 o3 e& R# c0 r& i) a nIndex = m_nSize;6 N+ I# K' c- x: a/ a/ W SetAtGrow(nIndex, newElement); YCArray_Add.Unlock(); SETIndex(cIndex,nIndex); return nIndex; };4 Y9 j0 F( I# Z" y* j9 \ int Append(const YCArray& src);# w/ m8 ^2 f0 a void Copy(const YCArray& src);// overloaded operator helpers
TYPE operator[](int nIndex) const;% [ ]# Q& m" x$ f TYPE& operator[](int nIndex); TYPE operator[](CString cIndex) const;. d N3 K1 L8 B TYPE& operator[](CString cIndex);2 c( l: _) X3 @2 b! L" `% P //YCArray<TYPE,ARG_TYPE> operator=(YCArray<TYPE,ARG_TYPE>& tparr)const; YCArray<TYPE,ARG_TYPE>& operator=(YCArray<TYPE,ARG_TYPE>& tparr); // Operations that move elements around void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1);2 S/ ]# o. H2 |" C4 W+ x6 l void RemoveAt(int nIndex, int nCount = 1);: x1 b, S$ D8 H' a void RemoveAt(CString cIndex,int nCount = 1); void InsertAt(int nStartIndex, YCArray* pNewArray);' i5 o3 B) m- d* J: }: x# | void InsertAt(ARG_TYPE newElement,int nIndex,CString cIndex);int GetIndex(CString cIndex);: O( o+ `( Z$ ~( I. Z; G( b CString GetIndex(int nIndex);
CString GetSign();
1 y' Z9 g2 m6 N( A7 ` int SetSign(CString& sign);// Implementation4 K7 w* J8 p4 A; T protected:/ g9 ?6 B9 @6 ^% Q p3 } TYPE** Ym_pData; // the actual array of data! q: d7 f% J" X, j int m_nSize; // # of elements (upperBound - 1)) A2 E( w1 ^: |8 I9 t4 B4 w int m_nMaxSize; // max allocated- z! z' S, w' g( \ int m_nGrowBy; // grow amount! J- L( Z q! O! e5 ?% w4 a: ? private:7 T- m8 P- o9 \' r$ y int lock_sign;& h0 ?; V, ?! J& T$ N, \( u/ L* J CString Sign;
int MAXSIGNTIME;CString* strIndex;* D B2 b! ]8 t+ F* f6 D4 G& Q7 E int strIndexNum;
1 M8 p" X5 v. L- o BOOL SetIndexSize(int nIndex); BOOL SETIndex(CString cIndex,int nIndex);$ K- U2 `) s$ Z7 R% w BOOL INSERTIndex(int nIndex,int nCount =1); BOOL DELIndex(int nIndex,int nCount = 1); BOOL DELIndex(CString cIndex,int nCount = 1);% q2 v8 K7 a5 f; r: S4 K/ y void DestructAllElement(int nIndex,int nCount)/ Q9 ~, a: @6 [8 T' g/ d {//销毁对象,包括每个指针指向的对象, l, p/ R6 \5 j% L; d DELIndex(nIndex,nCount); ASSERT(nIndex >= 0); ASSERT(nCount >= 0);2 u8 X4 f) Z6 s; c) ]% q) ` ASSERT(nIndex + nCount <= m_nSize); 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() delete Ym_pData;: r0 `* J) ^+ ? @& n( M }2 S3 \% c5 g2 e" p! H } }; void ConstructAllElements(int nIndex,int nCount) {//创建对象,包括 new 出每个指针指向的对象5 w5 g9 P, c4 k" u( j n //nIndex = 0;3 [6 t: j& g' t% G+ R memset((void*)(Ym_pData+nIndex), 0, nCount * sizeof(TYPE*)); for (; nCount--; nIndex++) Ym_pData[nIndex] = new TYPE; };; a. [; K* V5 X4 A3 P0 w7 G public:+ |2 K% b' I& }' f8 w" c2 m: b // Construction YCArray(); YCArray(YCArray<TYPE, ARG_TYPE>& tp);: O/ {# U; w& S# I( R# E) a* u ~YCArray(); void Serialize(CArchive&);$ G; c2 n) x) O #ifdef _DEBUG void Dump(CDumpContext&) const;6 ]- Z/ s) n, |: }. k. L2 q void AssertValid() const;7 R/ X# _) }- J, G" d #endif};
% S# ~+ |; y& _1 ? ~+ G" {//接上面
template<class TYPE, class ARG_TYPE> YCArray<TYPE, ARG_TYPE>::~YCArray(), |: D+ f8 W) C& O) [% x { ASSERT_VALID(this);
if (Ym_pData != NULL)
{" {% }# \$ y7 j: j DestructAllElement(0,m_nSize);% G9 H# _, z) M# G- c0 c* z1 F! r* A //DestructElements<TYPE>(Ym_pData, m_nSize);) p+ c2 z0 m( E" d9 J: ] delete[] (BYTE*)Ym_pData;5 G. Q ~( O# x8 ^( l }. t2 D# y" E& m. T, U( x9 u% ~ }% z4 x& w/ [/ \& g7 G; `) I: | template<class TYPE, class ARG_TYPE> CString YCArray<TYPE, ARG_TYPE>::GetSign() { lock_sign=0; V) J5 ]1 r L return Sign; } template<class TYPE, class ARG_TYPE> int YCArray<TYPE, ARG_TYPE>::SetSign(CString& sign) {; W8 i. u( {8 _4 n! ?* h8 @- Q9 ? int i=0; while(lock_sign&&i<MAXSIGNTIME){ ~( Y1 r5 K! X- [; N/ G Sleep(1);+ }0 T7 y0 w$ |- d) t# a' y i++;) m% e$ u& N- {# x } lock_sign=1; w) Z$ N0 K% H) ^% P4 w Sign=sign; return TRUE; }" A8 p) L* ?/ @ //用与把 nindex 后的索引往后推 nCount ,自动调整好buffer template<class TYPE, class ARG_TYPE>" e# v( ]) L6 O* n7 |. I, D! Q BOOL YCArray<TYPE, ARG_TYPE>::SetIndexSize(int nNewSize) { if(strIndexNum < nNewSize){ CString* tp = new CString[nNewSize];//新的buffer# A" E/ i2 Z+ a for(int i=0;i<strIndexNum;i++){//把老索引复制过来! Q1 Y% r$ f/ v2 j7 E! e tp = strIndex;1 \3 i/ C9 q" U% F }, M0 m# K: G0 X9 s( C for(i=strIndexNum;i<nNewSize;i++){ tp = "" ;2 [2 F: ^4 D; Z0 t" P+ T } delete[] strIndex ;% l- m S6 S' i& l5 C( t6 Q9 G strIndex = tp ; strIndexNum = nNewSize ; }else if(strIndexNum < nNewSize){2 q& a" c7 e% u0 g1 U$ J for(int i=nNewSize;i<strIndexNum;i++){ strIndex = "" ;* H) O$ q- e' E) P } }7 ]; G4 t# u, Z4 h) S4 K return TRUE; }* p2 a7 R+ Y% R# m template<class TYPE, class ARG_TYPE>* T3 N( h5 Z( Y BOOL YCArray<TYPE, ARG_TYPE>::INSERTIndex(int nIndex,int nCount /*=1*/)5 U+ Q4 w5 G0 r { CString* tp = new CString[m_nSize+nCount];//新的buffer for(int i=0;i<nIndex;i++){//把老索引复制过来 tp = strIndex;& B! \3 j! d5 F# V. _: } }int j =0 ; for(i=nIndex+nCount;i<m_nSize;i++){//把老索引复制过来 tp = strIndex[nIndex+j];( O; G( f) C* D8 i0 n: X& W j++;% s1 j! g, w( y+ E7 e8 K7 J3 V6 { } delete[] strIndex ;; v* M2 j, H$ C8 Z4 |6 G. g strIndex = tp ; return TRUE;5 r1 M: G) T& T6 L3 L; ?" |5 h/ D } template<class TYPE, class ARG_TYPE># I) ]2 a- R( J$ @9 ^/ U BOOL YCArray<TYPE, ARG_TYPE>::SETIndex(CString cIndex,int nIndex) {//在 nIndex 后面添加一个 字符串索引 strIndex[nIndex] = cIndex ; ?9 [. G; @0 H, {" C+ u return TRUE; }3 m0 j" {$ C2 R8 e6 T0 [2 r template<class TYPE, class ARG_TYPE>7 K4 u: J' _" |' h BOOL YCArray<TYPE, ARG_TYPE>:ELIndex(int nIndex,int nCount /*=1*/)' |# N2 x* ^, H$ T, ]: y {//需要在 m_nSize 变化之前调用!!. R! F" I* S$ e# W+ f ASSERT(nIndex >= 0);% ?3 ]4 h8 S- y; G/ u' m, x. e ASSERT(nCount >= 0);; C: u0 ~& M. O6 l) K5 Q [: r8 ~ ASSERT(nIndex + nCount <= m_nSize); int j =0 ;5 p% E [# U% p for(int i=nIndex+nCount;i<m_nSize;i++){//把老索引复制过来8 I/ I% X3 K" k% A& S strIndex[nIndex+j] = strIndex;8 M. [- P. r1 F5 w( ]: K8 ^ j++; }/ O! x% I# Q7 }- h6 \8 o' w4 K! n return TRUE;( @" O9 F1 V+ `6 w7 H# U } template<class TYPE, class ARG_TYPE>; n5 B$ S! @5 M3 h: j& x" { BOOL YCArray<TYPE, ARG_TYPE>:ELIndex(CString cIndex,int nCount /*=1*/) { int nIndex=this->GetIndex(cIndex);; A/ w& {4 B6 E; p! S return this->DELIndex(nIndex,nCount); }; b: `4 J+ {3 A# _" C$ s template<class TYPE, class ARG_TYPE>1 T' p7 w5 I# ~4 Y1 `: Z/ u int YCArray<TYPE, ARG_TYPE>::GetIndex(CString cIndex)3 q/ Y- e2 `% Q {//得到 cIndex 的数字索引 int nPos = -1;2 T% w3 ], v5 f+ C for(int i=0;i<m_nSize;i++){ if(strIndex == cIndex){ nPos = i ;break; } } return nPos;1 a% n: S( m8 x } template<class TYPE, class ARG_TYPE> CString YCArray<TYPE, ARG_TYPE>::GetIndex(int nIndex) {//返回 nIndex 的字符串索引) f, u9 l5 I* b& V return strIndex[nIndex];. F7 n! g) C) Y0 B } ///////////////////////////////////////////////////////////////////////////// // YCArray<TYPE, ARG_TYPE> inline functionstemplate<class TYPE, class ARG_TYPE>
AFX_INLINE int YCArray<TYPE, ARG_TYPE>::GetSize() const { return m_nSize; } template<class TYPE, class ARG_TYPE>3 b9 n' G+ K2 o* l AFX_INLINE int YCArray<TYPE, ARG_TYPE>::GetUpperBound() const { return m_nSize-1; }8 V. {6 [. }3 m9 p7 b. L template<class TYPE, class ARG_TYPE>4 C1 g' l# e* { W" l AFX_INLINE void YCArray<TYPE, ARG_TYPE>::RemoveAll()) Y$ e+ |$ C0 W' ^/ U" t* ~. Q { SetSize(0, -1); }1 ^3 |( d7 ?6 A: k( \" \5 L template<class TYPE, class ARG_TYPE> AFX_INLINE TYPE YCArray<TYPE, ARG_TYPE>::GetAt(int nIndex) const { ASSERT(nIndex >= 0 && nIndex < m_nSize); return *Ym_pData[nIndex]; } template<class TYPE, class ARG_TYPE> AFX_INLINE void YCArray<TYPE, ARG_TYPE>::SetAt(int nIndex, ARG_TYPE newElement)0 L ~) R5 q2 u# U! C { 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); return *Ym_pData[nIndex]; }template<class TYPE, class ARG_TYPE>% k1 C9 v( j+ I TYPE YCArray<TYPE, ARG_TYPE>::GetAt(CString cIndex) const: X) B0 g3 v, r. V: L y, F) L" Z {. j. d V: f( @) {. J" @% h4 n int nIndex=GetIndex(cIndex);! C* i, K9 g( \+ B: b$ G3 | return GetAt(nIndex);
} template<class TYPE, class ARG_TYPE>% J5 j' p1 Z! ]# f8 r H5 g/ f; M. ^ void YCArray<TYPE, ARG_TYPE>::SetAt(CString cIndex, ARG_TYPE newElement) {6 S) E0 T$ Q+ r# G! p+ V! T8 A7 ], O% Q int nIndex=GetIndex(cIndex); return SetAt(nIndex, newElement); }; M" E$ n' w9 X template<class TYPE, class ARG_TYPE> TYPE& YCArray<TYPE, ARG_TYPE>::ElementAt(CString cIndex)/ o% l6 N5 x7 c' ]: C+ _$ r+ _5 [ {& I* B' I$ k4 t* t6 b# w int nIndex=GetIndex(cIndex);! K0 \3 r2 T1 [( p return ElementAt(nIndex);8 T# L3 [+ M9 m8 }. K } template<class TYPE, class ARG_TYPE> AFX_INLINE const TYPE** YCArray<TYPE, ARG_TYPE>::GetData() const { return (const TYPE**)Ym_pData; }' {6 `2 N- Y5 P" X Q, o5 q- Y3 N5 y template<class TYPE, class ARG_TYPE> AFX_INLINE TYPE** YCArray<TYPE, ARG_TYPE>::GetData() { return (TYPE**)Ym_pData; }2 [0 h3 | O' p7 W* U! L H template<class TYPE, class ARG_TYPE>) S8 ~4 ?! A" r) h' Q. H8 n4 P AFX_INLINE int YCArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement,CString cIndex /* ="" */) { int nIndex = m_nSize;- p' ]. ]1 w2 N$ R! v3 Y4 E P' v SetAtGrow(nIndex, newElement); SETIndex(cIndex,nIndex);: n- O2 y% Y( x- Q' u2 t return nIndex; }6 }0 i4 ~" w7 c* D( N7 J2 r( ^ template<class TYPE, class ARG_TYPE> 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); }8 N( h( C8 t- s+ i0 @$ d template<class TYPE, class ARG_TYPE>, K1 O# G* b0 S6 Q/ { AFX_INLINE TYPE YCArray<TYPE, ARG_TYPE>:perator[](CString cIndex) const {+ ]) V- A* @" m4 O int nIndex=GetIndex(cIndex);return operator[](nIndex);7 {$ s5 Z& f$ v7 S: `1 F }3 f: C& ]0 p. i* q4 a3 S5 r# a5 B template<class TYPE, class ARG_TYPE>
AFX_INLINE TYPE& YCArray<TYPE, ARG_TYPE>:perator[](CString cIndex)* v- ^' ~6 [$ O0 d8 o r5 R3 \9 W# i { int nIndex=GetIndex(cIndex);0 v( \% \+ R, F N5 T8 F return operator[](nIndex);2 q7 C7 g9 V4 j }% U( R3 Y, d p2 e, q% Y x$ Z /* template<class TYPE, class ARG_TYPE> AFX_INLINE YCArray<TYPE,ARG_TYPE> YCArray<TYPE, ARG_TYPE>:perator=(YCArray<TYPE,ARG_TYPE>& tparr) const' X0 |) y1 `, ~5 _; d2 c { int i,j; for(i=0;i<tparr.GetSize();i++){" h4 \9 m, G7 D$ B j = GetIndex(tparr.GetIndex(i));: a5 t$ g9 Q: C, D& K6 L4 B9 a8 T if(j>-1){) o+ [ L5 }$ G2 @ operator[](tparr.GetIndex(i)) = tparr;) u$ B, x' H7 ]) I8 @. q }else{ Add(tparr,tparr.GetIndex(i));5 {& `+ P, T+ B. d/ w5 F% R" [9 e/ |. U }# x! b' F1 a8 ~ } return this;: t" a, Q9 r; X1 O# b) i } */ template<class TYPE, class ARG_TYPE> AFX_INLINE YCArray<TYPE,ARG_TYPE>& YCArray<TYPE, ARG_TYPE>:perator=(YCArray<TYPE,ARG_TYPE>& src)7 D: S, B4 {+ \ { ASSERT_VALID(this);- }( J3 O7 X# s Q7 @" C+ n ASSERT(this != &src); // cannot append to itselfSetSize(src.m_nSize);
for(int i=0;i<m_nSize;i++){ /*将此句修改为内存拷贝*///! ~2 n* n4 q2 l2 T *Ym_pData = *src.Ym_pData ;) s: ?2 z8 K! ?1 e4 ?9 p$ U9 [ //memcpy(Ym_pData,src.Ym_pData,sizeof(TYPE)); SETIndex(src.GetIndex(i),i); }- s7 d1 j% E3 g, `* F2 T return *this;, F2 l. Z8 g, ]9 m } ///////////////////////////////////////////////////////////////////////////// // YCArray<TYPE, ARG_TYPE> out-of-line functionstemplate<class TYPE, class ARG_TYPE>' k0 n- {; U! C. r/ a; F1 D4 B; X YCArray<TYPE, ARG_TYPE>::YCArray()+ H# B9 J9 G4 ] {* u5 a% h8 m* D- z7 h Ym_pData = NULL;, i/ b( _% P6 I8 _& D; x0 m( I strIndexNum = m_nSize = m_nMaxSize = m_nGrowBy = 0;$ F0 o: f" I4 u% U& I( O strIndex=NULL;MAXSIGNTIME=10;" b# p0 z0 @1 D1 h1 N' S j/ n }
template<class TYPE, class ARG_TYPE> YCArray<TYPE, ARG_TYPE>::YCArray(YCArray<TYPE, ARG_TYPE>& tp) {* s5 K4 Z( B, I+ U$ b, v) s6 F Ym_pData = NULL; strIndexNum = m_nSize = m_nMaxSize = m_nGrowBy = 0; strIndex=NULL;MAXSIGNTIME=10; operator=(tp);0 r o' W" l# N, n( [. Z4 p+ L }template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::SetSize(int nNewSize, int nGrowBy)# Y& y0 v: v/ @5 k6 B6 n7 D { ASSERT_VALID(this); ASSERT(nNewSize >= 0);if (nGrowBy != -1); @( t) L! y& D m_nGrowBy = nGrowBy; // set new size
if (nNewSize == 0){! q/ x2 Q( {, m9 y // shrink to nothing
if (Ym_pData != NULL){ DestructAllElement(0,m_nSize);: o! S, ^/ {4 ^# }' w/ U //DestructElements<TYPE>(Ym_pData, m_nSize);3 b: t1 {( [( M& \/ C$ q delete[] (BYTE*)Ym_pData;3 U9 e7 w9 y4 e# E! o7 d, {7 \2 |- R Ym_pData = NULL; } m_nSize = m_nMaxSize = 0;# D/ y& i( {8 P9 h" |: U% f+ Q: L" F } else if (Ym_pData == NULL){1 X; W/ i; ?+ ~2 `, z // create one with exact size+ b6 q7 j) z, j+ e H/ [ #ifdef SIZE_T_MAX ASSERT(nNewSize <= SIZE_T_MAX/sizeof(TYPE*)); // no overflow #endif% p1 o% K3 f: a i; e+ d$ K7 v# z8 a Ym_pData = (TYPE**) new BYTE[nNewSize * sizeof(TYPE*)]; ConstructAllElements(0,nNewSize);//ConstructElements<TYPE>(Ym_pData, nNewSize);4 Y x7 z$ x. w7 m m_nSize = m_nMaxSize = nNewSize; } else if (nNewSize <= m_nMaxSize){/ ~' M8 K4 ^3 w: d2 S. \ // it fits9 N: J# T a d+ r& I if (nNewSize > m_nSize)' j. u. s9 ~2 T3 a* S {$ t, m: ~- Z$ r! k B1 |$ v // initialize the new elements# a6 U& q. Z: v! b# F2 i6 v" W0 U( z ConstructAllElements(m_nSize,nNewSize-m_nSize);//ConstructElements<TYPE>(&Ym_pData[m_nSize], nNewSize-m_nSize); } else if (m_nSize > nNewSize); g' W m( k; A { // destroy the old elements2 {* B' Z1 g. E9 a% T DestructAllElement(nNewSize,m_nSize-nNewSize); //DestructElements<TYPE>(&Ym_pData[nNewSize], m_nSize-nNewSize);0 k# X- W1 Z0 u( y" b }, S- F% T4 P( I r: S$ T m_nSize = nNewSize;8 D; M' n( J0 D* N/ E } else { // otherwise, grow array int nGrowBy = m_nGrowBy; if (nGrowBy == 0) {: k1 h7 V, o) l2 b2 e2 l // heuristically determine growth when nGrowBy == 03 T$ f( P# ^2 g3 f# ~0 N( v // (this avoids heap fragmentation in many situations) nGrowBy = m_nSize / 8; nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);9 v8 S3 i* p) Z, f) v9 _ }2 T8 E* V4 U% M3 Y int nNewMax; if (nNewSize < m_nMaxSize + nGrowBy) nNewMax = m_nMaxSize + nGrowBy; // granularity! J2 `. H- R( b8 H else nNewMax = nNewSize; // no slushASSERT(nNewMax >= m_nMaxSize); // no wrap around/ \2 J' S# ^7 {4 X0 p- V9 g4 P _) ^ #ifdef SIZE_T_MAX# R \8 e" G% D9 N* u ASSERT(nNewMax <= SIZE_T_MAX/sizeof(TYPE)); // no overflow
#endif TYPE** pNewData = (TYPE**) new BYTE[nNewMax * sizeof(TYPE*)];//TYPE* pNewData = (TYPE*) new BYTE[nNewMax * sizeof(TYPE)];// copy new data from old
memcpy(pNewData, Ym_pData, m_nSize * sizeof(TYPE*));// construct remaining elements% Y8 G! \6 q4 M4 u ASSERT(nNewSize > m_nSize); //throw("/*wait for me --- yzhlinux*/");6 Z1 Q$ t6 K; ~4 p" Q delete[] (BYTE*)Ym_pData;
Ym_pData = pNewData;2 i& R1 p: W' P' V ConstructAllElements(m_nSize,nNewSize-m_nSize);//ConstructElements<TYPE>(&pNewData[m_nSize], nNewSize-m_nSize);// get rid of old stuff (note: no destructors called)
m_nSize = nNewSize; m_nMaxSize = nNewMax;0 U0 m e& b3 M" ]8 ?. y* g }. S6 u5 |) }' Z* W, U SetIndexSize(nNewSize);0 M) T2 i' M% k5 I& M }//接上面
7 B) o6 }$ m# z. J9 p template<class TYPE, class ARG_TYPE>
int YCArray<TYPE, ARG_TYPE>::Append(const YCArray& src) {- h* ~" F0 b* O( F ASSERT_VALID(this); ASSERT(this != &src); // cannot append to itselfint nOldSize = m_nSize;
SetSize(m_nSize + src.m_nSize);ConstructAllElements(nOldSize,src.m_nSize);
for(int i=nOldSize;i<m_nSize;i++){ C: w, N7 h$ @) h /*将此句修改为内存拷贝*/// *Ym_pData = *src.Ym_pData[i-nOldSize] ; //memcpy(Ym_pData,src.Ym_pData[i-nOldSize],sizeof(TYPE)); SETIndex(src.GetIndex(i-nOldSize),i); } /*wait for me*///CopyElements<TYPE>(Ym_pData + nOldSize, src.Ym_pData, src.m_nSize); return nOldSize;5 u* J& ^) M0 X# I* R }template<class TYPE, class ARG_TYPE>8 [6 d* H+ s% e: O# E$ C void YCArray<TYPE, ARG_TYPE>::Copy(const YCArray& src) e h8 h' L4 r& y- z- v7 v" @ {
ASSERT_VALID(this); ASSERT(this != &src); // cannot append to itselfSetSize(src.m_nSize);
for(int i=0;i<m_nSize;i++){ /*将此句修改为内存拷贝*///*Ym_pData = *src.Ym_pData ; memcpy(Ym_pData,src.Ym_pData,sizeof(TYPE)); SETIndex(src.GetIndex(i),i); } /*wait for me*///CopyElements<TYPE>(Ym_pData, src.Ym_pData, src.m_nSize); }template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::FreeExtra() { ASSERT_VALID(this);if (m_nSize != m_nMaxSize)
{ // shrink to desired size; Z* Q. y) l+ m+ b: c; Y2 l #ifdef SIZE_T_MAX ASSERT(m_nSize <= SIZE_T_MAX/sizeof(TYPE)); // no overflow# Y4 q- r/ f0 E1 I9 T4 N #endif4 p$ A- E, Q3 Q' F- \ TYPE* pNewData = NULL; if (m_nSize != 0)7 w; P- a+ g" k+ l5 v1 j$ m { pNewData = (TYPE**) new BYTE[m_nSize * sizeof(TYPE*)]; // copy new data from old memcpy(pNewData, Ym_pData, m_nSize * sizeof(TYPE*)); }// get rid of old stuff (note: no destructors called)/ v. D; l/ ^9 g# o1 m3 I1 p3 _8 N delete[] (BYTE*)Ym_pData;
Ym_pData = pNewData; m_nMaxSize = m_nSize;6 s5 F! O# G" a& A6 W C' H/ ` } } template<class TYPE, class ARG_TYPE>) i; T5 N7 W* I9 q1 U5 k void YCArray<TYPE, ARG_TYPE>::SetAtGrow(CString cIndex, ARG_TYPE newElement)$ D `$ h. l& N5 ^; @ {6 G) j: i$ j7 o int nIndex=GetIndex(cIndex);+ ]1 u1 ^" S. |& ]5 c+ ~2 L return SetAtGrow(nIndex,newElement);7 y8 m! A3 u: E- k, G } template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement) {9 _$ \ v9 r2 d1 ?; ~$ b8 r! E ASSERT_VALID(this);- `8 G5 I1 h' Z7 w, |( p6 Y5 h3 r! W ASSERT(nIndex >= 0);if (nIndex >= m_nSize)4 Q1 W+ f0 r7 t1 Q1 @ SetSize(nIndex+1, -1);
*Ym_pData[nIndex] = newElement; }template<class TYPE, class ARG_TYPE>9 c! f& M6 _9 M0 B+ A: F void YCArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount /*=1*/)5 V; o! b4 _$ q" A6 V {
ASSERT_VALID(this);: U- ^: D, r% t3 F, p ASSERT(nIndex >= 0); // will expand to meet need ASSERT(nCount > 0); // zero or negative size not allowedif (nIndex >= m_nSize)
{, t( q8 R& `# R5 K0 I // adding after the end of the array$ b5 ^/ D4 @5 a& z3 p: G. k SetSize(nIndex + nCount, -1); // grow so nIndex is valid } else+ w/ o/ r: N8 _/ M T! x9 @ {5 O& J% |+ u, o3 x // inserting in the middle of the array int nOldSize = m_nSize; SetSize(m_nSize + nCount, -1); // grow it to new size8 @# ?5 E1 U8 h3 Y- J, b& f // destroy intial data before copying over it /*不需要销毁了,因为 SetSize 的是指针*///DestructAllElement(nOldSize,nCount);4 L2 y3 i$ K; y //DestructElements<TYPE>(&Ym_pData[nOldSize], nCount);$ K- |# o- u3 C9 q& d9 | // shift old data up to fill gap; v( b0 R* w1 ?! I# {; _ memmove(&Ym_pData[nIndex+nCount], &Ym_pData[nIndex], (nOldSize-nIndex) * sizeof(TYPE*));// re-init slots we copied from8 [: r# v# m5 G /*不需要销毁了,因为 SetSize 的是指针*///ConstructAllElements(nIndex,nCount);//ConstructElements<TYPE>(&Ym_pData[nIndex], nCount);$ ^/ e$ ~7 h. G( I7 R% V! V }
// insert new value in the gap" {' J6 f! i' h2 v0 v: q; f ASSERT(nIndex + nCount <= m_nSize);
while (nCount--){7 P5 Y2 M, e$ ^# m* P h- d *Ym_pData[nIndex++] = newElement; }4 P% g! ?, `1 d }6 B0 j" x) Q, ^ J; H template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::RemoveAt(CString cIndex,int nCount /*=1*/)8 b3 ~' K" F1 k, z8 g( ? { int nIndex = GetIndex(cIndex); RemoveAt(nIndex,nCount); }- x% S$ z @" L/ a% _; i: Z template<class TYPE, class ARG_TYPE> void YCArray<TYPE, ARG_TYPE>::RemoveAt(int nIndex, int nCount /*=1*//*=1*/) { ASSERT_VALID(this);& c L" `, J( K, s ASSERT(nIndex >= 0);% g; r1 p" C7 H5 n& {3 a4 u# D ASSERT(nCount >= 0); ASSERT(nIndex + nCount <= m_nSize);# {/ _. E( o* S" [! H //yzh) \% x+ c' ~5 m; q* c DELIndex(nIndex);* c3 Y0 D! W; H //yzh // just remove a range8 z7 x, p6 Q( ]. h; k$ V int nMoveCount = m_nSize - (nIndex + nCount); //需要移动的数目 DestructAllElement(nIndex,nCount);$ o8 H: w3 b% P4 r //DestructElements<TYPE>(&Ym_pData[nIndex], nCount); if (nMoveCount) memmove(&Ym_pData[nIndex], &Ym_pData[nIndex + nCount],7 d8 x) J( t9 ]& p# R3 o nMoveCount * sizeof(TYPE*)); m_nSize -= nCount;2 u5 R+ D/ T! W }template<class TYPE, class ARG_TYPE>5 d% K* s( n8 x' F. m void YCArray<TYPE, ARG_TYPE>::InsertAt(int nStartIndex, YCArray* pNewArray)
{ ASSERT_VALID(this); ASSERT(pNewArray != NULL);6 i6 u3 }9 _# k' M0 u/ m ASSERT_VALID(pNewArray); o* o8 L1 \9 S ASSERT(nStartIndex >= 0);if (pNewArray->GetSize() > 0). W( r1 z3 w+ h( L# N) i9 f {8 U/ U5 i3 B" N, Z InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());$ ?- H% w! a% [3 N. q9 O for (int i = 0; i < pNewArray->GetSize(); i++)
SetAt(nStartIndex + i, pNewArray->GetAt(i)); u* _' W ^0 s } }0 U4 V- E7 \$ B$ a template<class TYPE, class ARG_TYPE>; V- s$ W6 B+ ], c( q9 l void YCArray<TYPE, ARG_TYPE>::InsertAt(ARG_TYPE newElement, int nIndex,CString cIndex)+ l7 Z6 Q( k: }4 H4 \" P/ X {9 \! a7 ?. h8 x; Z# J) R ADDIndex(cIndex,nIndex+1); InsertAt(newElement,nIndex); } template<class TYPE, class ARG_TYPE>+ L; H( k0 ^1 I: A void YCArray<TYPE, ARG_TYPE>::Serialize(CArchive& ar) { ASSERT_VALID(this); throw("/*wait for me --- yzhlinux*/"); CObject::Serialize(ar);, S* K2 n, _! w2 ~- Y if (ar.IsStoring()) G4 m4 h0 Y. W% A { ar.WriteCount(m_nSize); } else3 X0 V/ `# D2 t- h& y7 w { f7 Z& {0 D4 g1 Y# p% i+ ? DWORD nOldSize = ar.ReadCount();- w0 H& G/ x- l8 q% R SetSize(nOldSize, -1); } //SerializeElements<TYPE>(ar, Ym_pData, m_nSize);- y$ S$ z5 ?+ c- ^! j! l. l }#ifdef _DEBUG7 H$ `! x( S7 x0 \0 q R( ^7 F template<class TYPE, class ARG_TYPE>
void YCArray<TYPE, ARG_TYPE>::AssertValid() const {) M( x8 Q; T' N CObject::AssertValid();if (Ym_pData == NULL)
{- k" ~, x! Z; N4 Q' ] ASSERT(m_nSize == 0);0 |! f$ o! r5 r- G+ q& W/ B- @ ASSERT(m_nMaxSize == 0);5 t0 O! N3 O; l: C5 E } else1 C+ V6 [# ^& K' g5 Q) I3 o { ASSERT(m_nSize >= 0); ASSERT(m_nMaxSize >= 0); ASSERT(m_nSize <= m_nMaxSize);5 t4 J8 K" q- J- G1 N ASSERT(AfxIsValidAddress(Ym_pData, m_nMaxSize * sizeof(TYPE*))); }. G: S2 ?4 P; ^( Q9 L3 b0 V L }, h+ S# \, T3 ^% B( l6 K; i$ {2 Q% h template<class TYPE, class ARG_TYPE>5 h4 U8 T: `$ q# Y void YCArray<TYPE, ARG_TYPE>:ump(CDumpContext& dc) const { CObject:ump(dc);0 w8 q/ k2 a5 V9 q0 d throw("/*wait for me --- yzhlinux*/");: F, K" ^" K4 K% @ dc << "with " << m_nSize << " elements";1 ^+ a% Z6 M" i' }$ X7 V' Y$ I if (dc.GetDepth() > 0) {! D9 o% d3 S; D# ?. X dc << "\n";: Q- s% Z+ E+ }+ n# Q1 F3 b. V /*wait for me --- yzhlinux*/// DumpElements<TYPE>(dc, Ym_pData, m_nSize); }dc << "\n";! K3 X7 B- E) z( ] }: V- w3 Q2 s7 m- H" J #endif
#endif
//完
欢迎光临 下沙论坛 (http://bbs.xiasha.cn/) | Powered by Discuz! X3.3 |