一個學期課程結束,接著去公司改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
萬連文 閱讀(1295)
評論(4) 編輯 收藏 引用 所屬分類:
亂七八糟