一个学期课程结束,接着去公司改bug。以前做的一个网格控件老是出问题,于是下狠心重新实现一个!
准备实现一个网格数据结构,来存储网格控件数据。为了以后也可以使用,写了一个模板类,基本思想是写3个类:
/********************************************************************
created: 2006/01/12
created: 12:1:2006 14:30
filename: E:\MyProject\WLWLib\WLWGrid\WLWGrid.h
file path: E:\MyProject\WLWLib\WLWGrid
file base: WLWGrid
file ext: h
author: 万连文
purpose: 为了存储二维网格m×n数据,实现插入删除访问
用链表实现,适合大数据量(非海量数据)频繁插入删除使用
不适合稀疏矩阵使用,不适合海量数据,因为稀疏矩阵会浪费
很多单元格,海量数据会浪费很多单元格里面的指针
*********************************************************************/
// 网格单元类,存储数据,记录方位
template<class T>
class WLWGridCell
{
public:
WLWGridCell(T xData, WLWGridCell* pLeft=0, WLWGridCell* pUp=0, WLWGridCell* pRight=0, WLWGridCell* pDown=0)
{
SetData(xData);
SetLeft(pLeft);
SetRight(pRight);
SetUp(pUp);
SetDown(pDown);
m_lReserve = 0;
}
~WLWGridCell()
{
SetLeft(0);
SetRight(0);
SetUp(0);
SetDown(0);
}
// 设置数据
void SetData(T xData);
// 获得数据
T GetData();
// 设置保留数据
void SetReserve(long lReserve);
// 获得保数据
long GetReserve();
// 设置上方单元
void SetUp(WLWGridCell* pUp);
// 获得上方单元
WLWGridCell* GetUp();
// 设置下方单元
void SetDown(WLWGridCell* pDown);
// 获得下方单元
WLWGridCell* GetDown();
// 设置左方单元
void SetLeft(WLWGridCell* pLeft);
// 获得左方单元
WLWGridCell* GetLeft();
// 设置右方单元
void SetRight(WLWGridCell* pRight);
// 获得右方单元
WLWGridCell* GetRight();
private:
WLWGridCell* m_pUp; // 上方单元
WLWGridCell* m_pDown; // 下方单元
WLWGridCell* m_pLeft; // 左方单元
WLWGridCell* m_pRight; // 右方单元
T m_xData; // 存储数据
long m_lReserve; // 保留数据
};
// 网格行类,存储一行数据
template<class T>
class WLWGridRow
{
public:
WLWGridRow(WLWGridRow<T>* pUp=0, WLWGridRow<T>* pDown=0)
{
m_pHead = 0;
m_pTail = 0;
m_pCurr = 0;
m_lReserve = 0;
m_pUp = pUp;
m_pDown = pDown;
}
~WLWGridRow()
{
// 销毁所有网格
Empty();
}
// 获得当前的行头指针
WLWGridCell<T>* GetHead();
// 获得当前的行尾指针
WLWGridCell<T>* GetTail();
// 设置上一行
void SetUpRow(WLWGridRow<T>* pUp);
// 获得上一行
WLWGridRow<T>* GetUpRow();
// 设置下一行
void SetDownRow(WLWGridRow<T>* pDown);
// 获得下一行
WLWGridRow<T>* GetDownRow();
// 获得当前的游标指针
WLWGridCell<T>* GetCurrent();
// 按照索引获得单元格
WLWGridCell<T>* GetCellByIndex(int iIndex);
// 按照单元格获得索引,失败返回-1
int GetIndexByCell(WLWGridCell<T>* pCell);
// 当前指针右移
void MoveNext();
// 当前指针左移
void MoveBack();
// 当前指针行头
void MoveHead();
// 当前指针行尾
void MoveTail();
// 判断是否有下一个
bool HasNext();
// 判断是否有上一个
bool HasBack();
// 判断是否为空
bool IsEmpty();
// 清空行数据
void Empty();
// 设置保留数据
void SetReserve(long lReserve);
// 获得保数据
long GetReserve();
// 添加一个单元格,bRight=true表示添加在pos后面
// 可能修改m_pHead、m_pTail
// 返回<0表示添加失败;=0表示已存在;>0表示成功
int AddCell(WLWGridCell<T>* pCell, WLWGridCell<T>* pPos, bool bRight=true);
// 添加一个单元格,iIndex是索引,bRight=true表示添加在iIndex后面
// 可能修改m_pHead、m_pTail
// 返回<0表示添加失败;=0表示已存在;>0表示成功
int AddCell(WLWGridCell<T>* pCell, int iIndex, bool bRight=true);
// 删除指定单元格,可能修改m_pHead、m_pTail、m_pCurr
void DelCell(WLWGridCell<T>* pCell);
// 删除指定单元格,iIndex是索引,表示单元格的位置
// 可能修改m_pHead、m_pTail、m_pCurr
void DelCell(int iIndex);
// 查找指定值的单元格,失败返回-1,否则返回索引
int Find(T x);
// 重载[]运算符
WLWGridCell<T>* operator[](int iIndex);
private:
WLWGridCell<T>* m_pHead; // 记录一行的头
WLWGridCell<T>* m_pTail; // 记录一行的尾
WLWGridCell<T>* m_pCurr; // 当前游标位置,遍历的时候使用
WLWGridRow<T>* m_pUp; //上一行
WLWGridRow<T>* m_pDown; //下一行
long m_lReserve; // 保留数据
};
// 网格类,实现二维表格结构
template<class T>
class WLWGrid
{
public:
WLWGrid()
{
m_pHead = 0;
}
~WLWGrid()
{
Empty();
}
// 获得头行
WLWGridRow<T>* GetHead();
// 获得列数
int GetCols();
// 获得行数
int GetRows();
// 判断是否为空
bool IsEmpty();
// 清空表格
void Empty();
// 按照索引获得行
WLWGridRow<T>* GetRowByIndex(int iIndex);
// 按照行获得索引,失败返回-1
int GetIndexByRow(WLWGridRow<T>* pRow);
// 指定位置添加一行,bRight=true表示添加在pos后面
// 可能修改m_pHead
// 注意行的单元格数目必须等于Grid的列数,否则不添加
// 返回<0添加失败,0已存在,>0添加成功
int AddRow(WLWGridRow<T>* pRow, WLWGridRow<T>* pPos, bool bDown=true);
// 指定位置添加一行,iIndex是索引,bRight=true表示添加在pos后面
// 可能修改m_pHead
// 注意行的单元格数目必须等于Grid的列数,否则不添加
// 返回<0添加失败,0已存在,>0添加成功
int AddRow(WLWGridRow<T>* pRow, int iIndex, bool bDown=true);
// 指定位置添加值为xData的一行,bRight=true表示添加在pos后面
// 可能修改m_pHead
void AddRow(T xData, WLWGridRow<T>* pPos, bool bDown=true);
// 指定位置添加值为xData的一行,iIndex是索引,bRight=true表示添加在pos后面
// 可能修改m_pHead
void AddRow(T xData, int iIndex, bool bDown=true);
// 删除指定行,可能修改m_pHead
void DelRow(WLWGridRow<T>* pRow);
// 删除指定索引的行,可能修改m_pHead
void DelRow(int iIndex);
// 指定位置添加值为xData的一列,bRight表示在iIndex索引右面添加,否则在左面添加
// 添加成功返回true
bool AddCol(T xData, int iIndex, bool bRight=true);
// 删除下标为iIndex的一列
void DelCol(int iIndex);
// 重载[]运算符
WLWGridRow<T>* operator[](int iIndex);
private:
WLWGridRow<T>* m_pHead; // 头行
// 更新行单元格的指针,确保两行长度一致,否则会导致非预期结果(0指针除外)
void UpdateRowCellPtr(WLWGridRow<T>* pUp, WLWGridRow<T>* pDown);
};
化了接近一天时间写完,并经过简单测试,没有发现内存泄漏问题。
看测试截图 表现网格结构
下载网格数据结构及测试代码
希望大家下载使用,提出建议,报告bug,最重要是内存泄漏问题,谢谢!
posted on 2006-01-13 17:12
万连文 阅读(1285)
评论(4) 编辑 收藏 引用 所属分类:
乱七八糟