yzhlinux 发表于 2005-1-10 13:45:00

一个方便好用的数组类

<P>to Whanxy </P>
<P>int N;
N=StrToInt(Edit1-&gt;Text);
int RESULT;
哈哈,这样的代码很有意思哦.
在c++里没有现成的类似vb的redim那样可以自由定义数组边界的办法,很多人提供了一些数组类以实现你这样的需求,同样微软也提供了这样的模板类CArray ,你可以去参考这个摸板,不过 CArray 写的不够好只能给单线程的地方使用(后来个跟踪进去才发现是它的问题,没把偶气死)并且不能很好的支持使用 &amp; 引用内部的成员(底层机制的问题),我从新改写了它的底层实现,写了一个摸板类,给你用正好满足你的需求.:
#if !defined(CYCArray_INCLUDED)
#define CYCArray_INCLUDED
#include "afxtempl.h"
/**
* 动态数组的模板类 (Write By yzhlinux ,you could use it any time any way if you could email me about it <a href="http://bbs.echot.net/mailtyzhlinux@hotmail.com" target="_blank" >yzhlinux@hotmail.com</A>)
* 1.支持字符索引
* 2.方便的添加删除修改任意一项
* 最后更新 2004-8-9
**1.优化了字符索引的运作方式,使用数组存储
**2.重写了底层数据的存储,将连续性的存储方式改为了非连续,
*** 从而很好有效地支持了“引用”,并且让数据的删除增加变的更为快速
/////
* 用法句举例1:
* YCArray&lt;int,int&gt; test1 ;
* test1.Add("Number2",4);
* test1.Add("Number1",2);
* printf("%d %d",test1["Number1"],test1["Number2"]);
* 显示:
* 2 4
/////
* 用法句举例2:
* YCArray&lt;CString,CString&gt; test2 ;
* test2.Add("string2","hahahaha");
* test2.Add("string1","yes yes yes yes");
* printf("%s %s %s",test2["string1"],test2["string2],test2);
* 显示:
* yes yes yes yes hahahaha yes yes yes yes
/////
* 用法句举例3:
* YCArray&lt;CString,CString&gt; test3 ;
* 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);
* 显示:
* yes yes yes yes yes yes yes yes no no no
**/
/////////////////////////////////////////////////////////////////////////////
// YCArray&lt;TYPE, ARG_TYPE&gt;
#include &lt;afxmt.h&gt;
template&lt;class TYPE, class ARG_TYPE&gt;
class YCArray : public CObject
{
//friend YCArray&lt;TYPE, ARG_TYPE&gt;;
CCriticalSection YCArray_Add;
public:
// Attributes
int GetSize() const;
int GetUpperBound() const;
void SetSize(int nNewSize, int nGrowBy = -1);</P>
<P>// Operations
// Clean up
void FreeExtra();
void RemoveAll();</P>
<P>// Accessing elements
TYPE GetAt(int nIndex) const;
void SetAt(int nIndex, ARG_TYPE newElement);
TYPE&amp; ElementAt(int nIndex);</P>
<P>TYPE GetAt(CString cIndex) const;
void SetAt(CString cIndex, ARG_TYPE newElement);
TYPE&amp; ElementAt(CString cIndex);</P>
<P>// Direct Access to the element data (may return NULL)
const TYPE** GetData() const;
TYPE** GetData();</P>
<P>// Potentially growing the array
void SetAtGrow(int nIndex, ARG_TYPE newElement);
void SetAtGrow(CString cIndex, ARG_TYPE newElement);
int Add(ARG_TYPE newElement,CString cIndex = "");
int AddR(ARG_TYPE newElement,CString cIndex = "")//如果存在就替换
{
int nIndex = GetIndex(cIndex);
if(cIndex!=""&amp;&amp;nIndex &gt;-1){
   operator[](nIndex)=newElement;
}else{
   nIndex = m_nSize;
   SetAtGrow(nIndex, newElement);
   SETIndex(cIndex,nIndex);
   return nIndex;
}
}
int AddM(ARG_TYPE newElement,CString cIndex = "")
{
static int nIndex ;
YCArray_Add.Lock();
   nIndex = m_nSize;
   SetAtGrow(nIndex, newElement);
YCArray_Add.Unlock();
SETIndex(cIndex,nIndex);
return nIndex;
};
int Append(const YCArray&amp; src);
void Copy(const YCArray&amp; src);</P>
<P>// overloaded operator helpers
TYPE operator[](int nIndex) const;
TYPE&amp; operator[](int nIndex);
TYPE operator[](CString cIndex) const;
TYPE&amp; operator[](CString cIndex);
//YCArray&lt;TYPE,ARG_TYPE&gt; operator=(YCArray&lt;TYPE,ARG_TYPE&gt;&amp; tparr)const;
YCArray&lt;TYPE,ARG_TYPE&gt;&amp; operator=(YCArray&lt;TYPE,ARG_TYPE&gt;&amp; tparr);
// Operations that move elements around
void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1);
void RemoveAt(int nIndex, int nCount = 1);
void RemoveAt(CString cIndex,int nCount = 1);
void InsertAt(int nStartIndex, YCArray* pNewArray);
void InsertAt(ARG_TYPE newElement,int nIndex,CString cIndex);</P>
<P>int GetIndex(CString cIndex);
CString GetIndex(int nIndex);</P>
<P>CString GetSign();
int SetSign(CString&amp; sign);</P>
<P>// Implementation
protected:
TYPE** Ym_pData;   // the actual array of data
int m_nSize;   // # of elements (upperBound - 1)
int m_nMaxSize;// max allocated
int m_nGrowBy;   // grow amount
private:
int lock_sign;
CString Sign;
int MAXSIGNTIME;</P>
<P>CString* strIndex;
int strIndexNum;
BOOL SetIndexSize(int nIndex);
BOOL SETIndex(CString cIndex,int nIndex);
BOOL INSERTIndex(int nIndex,int nCount =1);
BOOL DELIndex(int nIndex,int nCount = 1);
BOOL DELIndex(CString cIndex,int nCount = 1);
void DestructAllElement(int nIndex,int nCount)
{//销毁对象,包括每个指针指向的对象
DELIndex(nIndex,nCount);
ASSERT(nIndex &gt;= 0);
ASSERT(nCount &gt;= 0);
ASSERT(nIndex + nCount &lt;= m_nSize);
if(nCount&gt;0&amp;&amp;m_nSize&gt;0){
   for(int i =nIndex;i&lt;nIndex+nCount;i++){
    //Ym_pData-&gt;~TYPE(); // 由于ConstructAllElements 中是 Ym_pData = new TYPE;所以不需要Ym_pData-&gt;~TYPE()
    delete Ym_pData;
   }
}
};
void ConstructAllElements(int nIndex,int nCount)
{//创建对象,包括 new 出每个指针指向的对象
//nIndex = 0;
memset((void*)(Ym_pData+nIndex), 0, nCount * sizeof(TYPE*));
for (; nCount--; nIndex++)
   Ym_pData = new TYPE;
};
public:
// Construction
YCArray();
YCArray(YCArray&lt;TYPE, ARG_TYPE&gt;&amp; tp);
~YCArray();
void Serialize(CArchive&amp;);
#ifdef _DEBUG
void Dump(CDumpContext&amp;) const;
void AssertValid() const;
#endif</P>
<P>};</P>
[此贴子已经被作者于2005-1-10 14:04:39编辑过]

yzhlinux 发表于 2005-1-10 13:56:00

<P>//接上面</P><P>
template&lt;class TYPE, class ARG_TYPE&gt;
YCArray&lt;TYPE, ARG_TYPE&gt;::~YCArray()
{
ASSERT_VALID(this);</P><P> if (Ym_pData != NULL)
{
DestructAllElement(0,m_nSize);
//DestructElements&lt;TYPE&gt;(Ym_pData, m_nSize);
delete[] (BYTE*)Ym_pData;
}
}
template&lt;class TYPE, class ARG_TYPE&gt;
CString YCArray&lt;TYPE, ARG_TYPE&gt;::GetSign()
{
lock_sign=0;
return Sign;
}
template&lt;class TYPE, class ARG_TYPE&gt;
int YCArray&lt;TYPE, ARG_TYPE&gt;::SetSign(CString&amp; sign)
{
int i=0;
while(lock_sign&amp;&amp;i&lt;MAXSIGNTIME){
Sleep(1);
i++;
}
lock_sign=1;
Sign=sign;
return TRUE;
}
//用与把 nindex 后的索引往后推 nCount ,自动调整好buffer
template&lt;class TYPE, class ARG_TYPE&gt;
BOOL YCArray&lt;TYPE, ARG_TYPE&gt;::SetIndexSize(int nNewSize)
{
if(strIndexNum &lt; nNewSize){
CString* tp = new CString;//新的buffer
for(int i=0;i&lt;strIndexNum;i++){//把老索引复制过来
   tp = strIndex;
}
for(i=strIndexNum;i&lt;nNewSize;i++){
   tp = "" ;
}
delete[] strIndex ;
strIndex = tp ;
strIndexNum= nNewSize ;
}else if(strIndexNum &lt; nNewSize){
for(int i=nNewSize;i&lt;strIndexNum;i++){
   strIndex = "" ;
}
}
return TRUE;
}
template&lt;class TYPE, class ARG_TYPE&gt;
BOOL YCArray&lt;TYPE, ARG_TYPE&gt;::INSERTIndex(int nIndex,int nCount /*=1*/)
{
CString* tp = new CString;//新的buffer
for(int i=0;i&lt;nIndex;i++){//把老索引复制过来
tp = strIndex;
}int j =0 ;
for(i=nIndex+nCount;i&lt;m_nSize;i++){//把老索引复制过来
tp = strIndex;
j++;
}
delete[] strIndex ;
strIndex = tp ;
return TRUE;
}
template&lt;class TYPE, class ARG_TYPE&gt;
BOOL YCArray&lt;TYPE, ARG_TYPE&gt;::SETIndex(CString cIndex,int nIndex)
{//在 nIndex 后面添加一个 字符串索引
strIndex = cIndex ;
return TRUE;
}
template&lt;class TYPE, class ARG_TYPE&gt;
BOOL YCArray&lt;TYPE, ARG_TYPE&gt;::DELIndex(int nIndex,int nCount /*=1*/)
{//需要在 m_nSize 变化之前调用!!
ASSERT(nIndex &gt;= 0);
ASSERT(nCount &gt;= 0);
ASSERT(nIndex + nCount &lt;= m_nSize);
int j =0 ;
for(int i=nIndex+nCount;i&lt;m_nSize;i++){//把老索引复制过来
strIndex = strIndex;
j++;
}
return TRUE;
}
template&lt;class TYPE, class ARG_TYPE&gt;
BOOL YCArray&lt;TYPE, ARG_TYPE&gt;::DELIndex(CString cIndex,int nCount /*=1*/)
{
int nIndex=this-&gt;GetIndex(cIndex);
return this-&gt;DELIndex(nIndex,nCount);
}
template&lt;class TYPE, class ARG_TYPE&gt;
int YCArray&lt;TYPE, ARG_TYPE&gt;::GetIndex(CString cIndex)
{//得到 cIndex 的数字索引
int nPos = -1;
for(int i=0;i&lt;m_nSize;i++){
if(strIndex == cIndex){
   nPos = i ;break;
}
}
return nPos;
}
template&lt;class TYPE, class ARG_TYPE&gt;
CString YCArray&lt;TYPE, ARG_TYPE&gt;::GetIndex(int nIndex)
{//返回 nIndex 的字符串索引
return strIndex;
}
/////////////////////////////////////////////////////////////////////////////
// YCArray&lt;TYPE, ARG_TYPE&gt; inline functions</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE int YCArray&lt;TYPE, ARG_TYPE&gt;::GetSize() const
{ return m_nSize; }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE int YCArray&lt;TYPE, ARG_TYPE&gt;::GetUpperBound() const
{ return m_nSize-1; }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE void YCArray&lt;TYPE, ARG_TYPE&gt;::RemoveAll()
{ SetSize(0, -1); }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE TYPE YCArray&lt;TYPE, ARG_TYPE&gt;::GetAt(int nIndex) const
{ ASSERT(nIndex &gt;= 0 &amp;&amp; nIndex &lt; m_nSize);
return *Ym_pData; }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE void YCArray&lt;TYPE, ARG_TYPE&gt;::SetAt(int nIndex, ARG_TYPE newElement)
{ ASSERT(nIndex &gt;= 0 &amp;&amp; nIndex &lt; m_nSize);
*(Ym_pData) = newElement; }</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE TYPE&amp; YCArray&lt;TYPE, ARG_TYPE&gt;::ElementAt(int nIndex)
{ ASSERT(nIndex &gt;= 0 &amp;&amp; nIndex &lt; m_nSize);
return *Ym_pData; }</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
TYPE YCArray&lt;TYPE, ARG_TYPE&gt;::GetAt(CString cIndex) const
{
int nIndex=GetIndex(cIndex);
return GetAt(nIndex);
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::SetAt(CString cIndex, ARG_TYPE newElement)
{
int nIndex=GetIndex(cIndex);
return SetAt(nIndex, newElement);
}
template&lt;class TYPE, class ARG_TYPE&gt;
TYPE&amp; YCArray&lt;TYPE, ARG_TYPE&gt;::ElementAt(CString cIndex)
{
int nIndex=GetIndex(cIndex);
return ElementAt(nIndex);
}
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE const TYPE** YCArray&lt;TYPE, ARG_TYPE&gt;::GetData() const
{ return (const TYPE**)Ym_pData; }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE TYPE** YCArray&lt;TYPE, ARG_TYPE&gt;::GetData()
{ return (TYPE**)Ym_pData; }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE int YCArray&lt;TYPE, ARG_TYPE&gt;::Add(ARG_TYPE newElement,CString cIndex /* ="" */)
{ int nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
SETIndex(cIndex,nIndex);
return nIndex; }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE TYPE YCArray&lt;TYPE, ARG_TYPE&gt;::operator[](int nIndex) const
{ return GetAt(nIndex); }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE TYPE&amp; YCArray&lt;TYPE, ARG_TYPE&gt;::operator[](int nIndex)
{ return ElementAt(nIndex); }
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE TYPE YCArray&lt;TYPE, ARG_TYPE&gt;::operator[](CString cIndex) const
{
int nIndex=GetIndex(cIndex);</P><P> return operator[](nIndex);
}
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE TYPE&amp; YCArray&lt;TYPE, ARG_TYPE&gt;::operator[](CString cIndex)
{
int nIndex=GetIndex(cIndex);
return operator[](nIndex);
}
/*
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE YCArray&lt;TYPE,ARG_TYPE&gt; YCArray&lt;TYPE, ARG_TYPE&gt;::operator=(YCArray&lt;TYPE,ARG_TYPE&gt;&amp; tparr) const
{
int i,j;
for(i=0;i&lt;tparr.GetSize();i++){
j = GetIndex(tparr.GetIndex(i));
if(j&gt;-1){
   operator[](tparr.GetIndex(i)) = tparr;
}else{
   Add(tparr,tparr.GetIndex(i));
}
}
return this;
}
*/
template&lt;class TYPE, class ARG_TYPE&gt;
AFX_INLINE YCArray&lt;TYPE,ARG_TYPE&gt;&amp; YCArray&lt;TYPE, ARG_TYPE&gt;::operator=(YCArray&lt;TYPE,ARG_TYPE&gt;&amp; src)
{
ASSERT_VALID(this);
ASSERT(this != &amp;src);   // cannot append to itself</P><P> SetSize(src.m_nSize);
for(int i=0;i&lt;m_nSize;i++){
/*将此句修改为内存拷贝*///
*Ym_pData = *src.Ym_pData ;
//memcpy(Ym_pData,src.Ym_pData,sizeof(TYPE));
SETIndex(src.GetIndex(i),i);
}
return *this;
}
/////////////////////////////////////////////////////////////////////////////
// YCArray&lt;TYPE, ARG_TYPE&gt; out-of-line functions</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
YCArray&lt;TYPE, ARG_TYPE&gt;::YCArray()
{
Ym_pData = NULL;
strIndexNum = m_nSize = m_nMaxSize = m_nGrowBy = 0;
strIndex=NULL;MAXSIGNTIME=10;
}
template&lt;class TYPE, class ARG_TYPE&gt;
YCArray&lt;TYPE, ARG_TYPE&gt;::YCArray(YCArray&lt;TYPE, ARG_TYPE&gt;&amp; tp)
{
Ym_pData = NULL;
strIndexNum = m_nSize = m_nMaxSize = m_nGrowBy = 0;
strIndex=NULL;MAXSIGNTIME=10;
operator=(tp);
}</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::SetSize(int nNewSize, int nGrowBy)
{
ASSERT_VALID(this);
ASSERT(nNewSize &gt;= 0);</P><P> if (nGrowBy != -1)
m_nGrowBy = nGrowBy;// set new size</P><P> if (nNewSize == 0){
// shrink to nothing
if (Ym_pData != NULL){
   DestructAllElement(0,m_nSize);
   //DestructElements&lt;TYPE&gt;(Ym_pData, m_nSize);
   delete[] (BYTE*)Ym_pData;
   Ym_pData = NULL;
}
m_nSize = m_nMaxSize = 0;
} else if (Ym_pData == NULL){
// create one with exact size
#ifdef SIZE_T_MAX
ASSERT(nNewSize &lt;= SIZE_T_MAX/sizeof(TYPE*));    // no overflow
#endif
Ym_pData = (TYPE**) new BYTE;
ConstructAllElements(0,nNewSize);//ConstructElements&lt;TYPE&gt;(Ym_pData, nNewSize);
m_nSize = m_nMaxSize = nNewSize;
} else if (nNewSize &lt;= m_nMaxSize){
// it fits
if (nNewSize &gt; m_nSize)
{
   // initialize the new elements
   ConstructAllElements(m_nSize,nNewSize-m_nSize);//ConstructElements&lt;TYPE&gt;(&amp;Ym_pData, nNewSize-m_nSize);
}
else if (m_nSize &gt; nNewSize)
{
   // destroy the old elements
   DestructAllElement(nNewSize,m_nSize-nNewSize);
   //DestructElements&lt;TYPE&gt;(&amp;Ym_pData, m_nSize-nNewSize);
}
m_nSize = nNewSize;
}
else
{
// otherwise, grow array
int nGrowBy = m_nGrowBy;
if (nGrowBy == 0)
{
   // heuristically determine growth when nGrowBy == 0
   //(this avoids heap fragmentation in many situations)
   nGrowBy = m_nSize / 8;
   nGrowBy = (nGrowBy &lt; 4) ? 4 : ((nGrowBy &gt; 1024) ? 1024 : nGrowBy);
}
int nNewMax;
if (nNewSize &lt; m_nMaxSize + nGrowBy)
   nNewMax = m_nMaxSize + nGrowBy;// granularity
else
   nNewMax = nNewSize;// no slush</P><P>ASSERT(nNewMax &gt;= m_nMaxSize);// no wrap around
#ifdef SIZE_T_MAX
ASSERT(nNewMax &lt;= SIZE_T_MAX/sizeof(TYPE)); // no overflow
#endif
TYPE** pNewData = (TYPE**) new BYTE;//TYPE* pNewData = (TYPE*) new BYTE;</P><P>// copy new data from old
memcpy(pNewData, Ym_pData, m_nSize * sizeof(TYPE*));</P><P>// construct remaining elements
ASSERT(nNewSize &gt; m_nSize);//throw("/*wait for me --- yzhlinux*/");
delete[] (BYTE*)Ym_pData;
Ym_pData = pNewData;
ConstructAllElements(m_nSize,nNewSize-m_nSize);//ConstructElements&lt;TYPE&gt;(&amp;pNewData, nNewSize-m_nSize);</P><P>// get rid of old stuff (note: no destructors called)
m_nSize = nNewSize;
m_nMaxSize = nNewMax;
}
SetIndexSize(nNewSize);
}
</P>

yzhlinux 发表于 2005-1-10 13:58:00

<P>//接上面</P><P>
template&lt;class TYPE, class ARG_TYPE&gt;
int YCArray&lt;TYPE, ARG_TYPE&gt;::Append(const YCArray&amp; src)
{
ASSERT_VALID(this);
ASSERT(this != &amp;src);   // cannot append to itself</P><P> int nOldSize = m_nSize;
SetSize(m_nSize + src.m_nSize);</P><P> ConstructAllElements(nOldSize,src.m_nSize);
for(int i=nOldSize;i&lt;m_nSize;i++){
/*将此句修改为内存拷贝*///
*Ym_pData = *src.Ym_pData ;
//memcpy(Ym_pData,src.Ym_pData,sizeof(TYPE));
SETIndex(src.GetIndex(i-nOldSize),i);
}
/*wait for me*///CopyElements&lt;TYPE&gt;(Ym_pData + nOldSize, src.Ym_pData, src.m_nSize);
return nOldSize;
}</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::Copy(const YCArray&amp; src)
{
ASSERT_VALID(this);
ASSERT(this != &amp;src);   // cannot append to itself</P><P> SetSize(src.m_nSize);
for(int i=0;i&lt;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&lt;TYPE&gt;(Ym_pData, src.Ym_pData, src.m_nSize);
}</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::FreeExtra()
{
ASSERT_VALID(this);</P><P> if (m_nSize != m_nMaxSize)
{
// shrink to desired size
#ifdef SIZE_T_MAX
ASSERT(m_nSize &lt;= SIZE_T_MAX/sizeof(TYPE)); // no overflow
#endif
TYPE* pNewData = NULL;
if (m_nSize != 0)
{
   pNewData = (TYPE**) new BYTE;
   // copy new data from old
   memcpy(pNewData, Ym_pData, m_nSize * sizeof(TYPE*));
}</P><P>// get rid of old stuff (note: no destructors called)
delete[] (BYTE*)Ym_pData;
Ym_pData = pNewData;
m_nMaxSize = m_nSize;
}
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::SetAtGrow(CString cIndex, ARG_TYPE newElement)
{
int nIndex=GetIndex(cIndex);
return SetAtGrow(nIndex,newElement);
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::SetAtGrow(int nIndex, ARG_TYPE newElement)
{
ASSERT_VALID(this);
ASSERT(nIndex &gt;= 0);</P><P> if (nIndex &gt;= m_nSize)
SetSize(nIndex+1, -1);
*Ym_pData = newElement;
}</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::InsertAt(int nIndex, ARG_TYPE newElement, int nCount /*=1*/)
{
ASSERT_VALID(this);
ASSERT(nIndex &gt;= 0);    // will expand to meet need
ASSERT(nCount &gt; 0);   // zero or negative size not allowed</P><P> if (nIndex &gt;= m_nSize)
{
// adding after the end of the array
SetSize(nIndex + nCount, -1);   // grow so nIndex is valid
}
else
{
// 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
/*不需要销毁了,因为 SetSize 的是指针*///DestructAllElement(nOldSize,nCount);
//DestructElements&lt;TYPE&gt;(&amp;Ym_pData, nCount);
// shift old data up to fill gap
memmove(&amp;Ym_pData, &amp;Ym_pData,
   (nOldSize-nIndex) * sizeof(TYPE*));</P><P>// re-init slots we copied from
/*不需要销毁了,因为 SetSize 的是指针*///ConstructAllElements(nIndex,nCount);//ConstructElements&lt;TYPE&gt;(&amp;Ym_pData, nCount);
}</P><P> // insert new value in the gap
ASSERT(nIndex + nCount &lt;= m_nSize);
while (nCount--){
*Ym_pData = newElement;
}
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::RemoveAt(CString cIndex,int nCount /*=1*/)
{
int nIndex = GetIndex(cIndex);
RemoveAt(nIndex,nCount);
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::RemoveAt(int nIndex, int nCount /*=1*//*=1*/)
{
ASSERT_VALID(this);
ASSERT(nIndex &gt;= 0);
ASSERT(nCount &gt;= 0);
ASSERT(nIndex + nCount &lt;= m_nSize);
//yzh
DELIndex(nIndex);
//yzh
// just remove a range
int nMoveCount = m_nSize - (nIndex + nCount); //需要移动的数目
DestructAllElement(nIndex,nCount);
//DestructElements&lt;TYPE&gt;(&amp;Ym_pData, nCount);
if (nMoveCount)
memmove(&amp;Ym_pData, &amp;Ym_pData,
   nMoveCount * sizeof(TYPE*));
m_nSize -= nCount;
}</P><P>template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::InsertAt(int nStartIndex, YCArray* pNewArray)
{
ASSERT_VALID(this);
ASSERT(pNewArray != NULL);
ASSERT_VALID(pNewArray);
ASSERT(nStartIndex &gt;= 0);</P><P> if (pNewArray-&gt;GetSize() &gt; 0)
{
InsertAt(nStartIndex, pNewArray-&gt;GetAt(0), pNewArray-&gt;GetSize());
for (int i = 0; i &lt; pNewArray-&gt;GetSize(); i++)
   SetAt(nStartIndex + i, pNewArray-&gt;GetAt(i));
}
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::InsertAt(ARG_TYPE newElement, int nIndex,CString cIndex)
{
ADDIndex(cIndex,nIndex+1);
InsertAt(newElement,nIndex);
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::Serialize(CArchive&amp; ar)
{
ASSERT_VALID(this);
throw("/*wait for me --- yzhlinux*/");
CObject::Serialize(ar);
if (ar.IsStoring())
{
ar.WriteCount(m_nSize);
}
else
{
DWORD nOldSize = ar.ReadCount();
SetSize(nOldSize, -1);
}
//SerializeElements&lt;TYPE&gt;(ar, Ym_pData, m_nSize);
}</P><P>#ifdef _DEBUG
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::AssertValid() const
{
CObject::AssertValid();</P><P> if (Ym_pData == NULL)
{
ASSERT(m_nSize == 0);
ASSERT(m_nMaxSize == 0);
}
else
{
ASSERT(m_nSize &gt;= 0);
ASSERT(m_nMaxSize &gt;= 0);
ASSERT(m_nSize &lt;= m_nMaxSize);
ASSERT(AfxIsValidAddress(Ym_pData, m_nMaxSize * sizeof(TYPE*)));
}
}
template&lt;class TYPE, class ARG_TYPE&gt;
void YCArray&lt;TYPE, ARG_TYPE&gt;::Dump(CDumpContext&amp; dc) const
{
CObject::Dump(dc);
throw("/*wait for me --- yzhlinux*/");
dc &lt;&lt; "with " &lt;&lt; m_nSize &lt;&lt; " elements";
if (dc.GetDepth() &gt; 0)
{
dc &lt;&lt; "\n";
/*wait for me --- yzhlinux*///DumpElements&lt;TYPE&gt;(dc, Ym_pData, m_nSize);
}</P><P> dc &lt;&lt; "\n";
}
#endif </P><P>#endif </P><P>//完</P>

Eagle 发表于 2005-1-10 14:44:00

太长了点,叶师兄应该打包上传的。

yzhlinux 发表于 2005-1-10 15:47:00

<DIV class=quote><B>以下是引用<I>Eagle</I>在2005-1-10 14:44:00的发言:</B>
太长了点,叶师兄应该打包上传的。</DIV>


就是因为发不了文件啊,奇怪,现在不能上传文件了,不然不用那么辛苦

Eagle 发表于 2005-1-13 23:02:00

先传到帖图区……

管理员 发表于 2005-4-11 21:15:00

赚帖子不好吗

yzhlinux 发表于 2005-6-3 14:56:00

现在可以传文件了,附上,好用的摸板数组类,支持 ATL 可以在任何地方使用。

游侠无极限 发表于 2005-6-3 17:55:00

std::map 模板的作用好像就是这样的……
页: [1]
查看完整版本: 一个方便好用的数组类