hur.cn - 华软网

 热门搜索

一个动态容器的编写代码

  作者:未知    来源:网络    更新时间:2010/8/3
时间匆忙,根据需要编写了一个类似动态字符串的结构体。本意是为了保存一个动态变长的字符串。时间和水平问题,实现的不是很好,请各位DX给看看给些指点和优化建议。由于需求简单,实现上就没有考虑太多的接口设计。

我的实现如下:
C++">
/*
1/ 动态内存分配
2/ 内存自动回收
3/ 注意构造函数、拷贝构造函数、赋值操作符的重载实现以及具体的应用要求
*/
typedef struct _CONTAINOR
{
int nCount; // 元素个数
int nSize; // 已经分配的pszBuffer缓存大小
char* pszBuffer; // 缓存
// 初始化构造函数
_CONTAINOR()
{
nCount = 0;
nSize = 0;
pszBuffer = NULL;
// 初始化内存分配128字节
AllocBuffer(128);
}
// 析构函数 -- 负责内存的动态回收
~_CONTAINOR()
{ // 回收内存,避免内存泄露
if (pszBuffer)
{
delete []pszBuffer;
pszBuffer = NULL;
}
}
// 拷贝构造函数
_CONTAINOR(const _CONTAINOR& stData)
{
// 元素个数
nCount = stData.nCount;
// 缓存空间大小
nSize = stData.nSize;
// 回收原有内存
delete []pszBuffer;
// 分配新的内存大小、初始化
pszBuffer = new char[stData.nSize];
memset(pszBuffer,0,stData.nSize);
// 拷贝数据
memcpy(pszBuffer,stData.pszBuffer,stData.nCount*2);
}
// 赋值操作符重载
const _CONTAINOR& operator = (const _CONTAINOR& stData)
{
nCount = stData.nCount;
nSize = stData.nSize;
delete []pszBuffer;
pszBuffer = new char[stData.nSize];
memset(pszBuffer,0,stData.nSize);
memcpy(pszBuffer,stData.pszBuffer,stData.nCount*2);
return *this;
}
// 分配初始buffer内存
void AllocBuffer(int nLen = 128)
{
nSize = nLen;
pszBuffer = new char[nLen];
memset(pszBuffer,0,nLen);
}
// 追加分配内存
void ReallocBuffer(int nLen)
{
// 分配足够大内存 nSize + nLen
char* pTemp = new char[nSize + nLen];
memset(pTemp,0,nSize + nLen);
// 拷贝现有数据到新的内存
memcpy(pTemp,pszBuffer,nCount*2);
// 释放原来的内存
delete []pszBuffer;
// 设置新的指针指向新分配的内存地址
pszBuffer = pTemp;
// 调整nSize为新分配的内存大小
nSize += nLen;
}
// 追加数据到buffer
void AppendData(const _FLAG& stMsg)
{
if ((nCount+1)*2>nSize)
{ // 缓存空间已经不够使用,重新追加内存
ReallocBuffer(128);
}
// 追加数据到buffer
memcpy(pszBuffer+nCount*2,stMsg.szMsg,2);
// 消息元素计数器增加
++nCount;
}
// 连接两个容器的内容
void InsertData(const _CONTAINOR& stSource)
{
char* pTemp = NULL;
if ((stSource.nCount+nCount)*2>nSize)
{
pTemp = new char[nSize + stSource.nSize];
// 新的缓存空间大小
nSize = nSize + stSource.nSize;
}
else
{
pTemp = new char[nSize];
}
// 头部数据
memcpy(pTemp,stSource.pszBuffer,stSource.nCount*2);
// 尾部数据
memcpy(pTemp+stSource.nCount*2,pszBuffer,nCount*2);
// 回收内存
delete []pszBuffer;
// 指针指向新分配内存
pszBuffer = pTemp;
// 消息元素个数增加
nCount += stSource.nCount;
}
// 释放内存
void ReleaseBuffer(void)
{
if (pszBuffer)
{
delete []pszBuffer;
pszBuffer = NULL;
}
}
} CONTAINOR;

---华软 网友回答---
沙发, mark
提几点,不对请指出

1、拷贝构造函数,不需要做:
        // 回收内存
        delete []pszBuffer;
   回为此时尚未构造,pszBuffer的值不确定,可能会造成异常
2、赋值操作符重载 , 这个要防止自我赋值
if (this == &strData)
{
   return *this;
}

   
---华软网友回复---
多谢!
拷贝构造函数不需要回收原来的内存么?因为我实在构造函数内实现的内存分配,析构实现的内存回收。拷贝构造函数的用法大多如下:
CLASS obj1;
CLASS obj2(obj1); // 这里直接执行了拷贝构造?还没有分配内存是吧?

第二个的确是我没有考虑到。
引用楼主 teleinfor 的回复:
时间匆忙,根据需要编写了一个类似动态字符串的结构体。本意是为了保存一个动态变长的字符串。时间和水平问题,实现的不是很好,请各位DX给看看给些指点和优化建议。由于需求简单,实现上就没有考虑太多的接口设计。

我的实现如下:

C/C++ code

/*
    1/ 动态内存分配
    2/ 内存自动回收
    3/ 注意构造函数、拷贝构造函数、赋值操作符的重载实现以及具体的……

---华软网友回复---
拷贝构造函数之前,你的内存从来没有分配过,又谈什么回收?

---华软网友回复---
另外,你的所有函数都是基于“在实例生存周期的任何时候,缓冲区都是存在的”这一前提条件,因此你的ReleaseBuffer绝不可能被调用,否则你的程序一定会崩溃。那你要这么个函数干什么?
还有,你的AllocBuffer也同样绝不能被外部程序调用,否则会内存泄漏,因此应该声明为private。还有几个成员变量也应该是private。
---华软网友回复---
哦,确实没有理解拷贝构造函数。清楚了。
引用 3 楼 xxd_qd 的回复:
拷贝构造函数之前,你的内存从来没有分配过,又谈什么回收?

---华软网友回复---
关于综合性能实现方面,大家有何进一步的建议?
---华软网友回复---
lz 强人。。。。。我基础太不扎实,,,看起来都吃力。。。      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。