打算先把基礎(chǔ)的東西組織起來,作為一個(gè)“大庫(kù)”(見上一篇《小庫(kù)還是大庫(kù)?》)。然后填加各個(gè)實(shí)用功能,作為一個(gè)個(gè)小庫(kù)或者大庫(kù),過段時(shí)間再想辦法組織整理了。
首先是類型系統(tǒng),我想來想去,覺得還是必須整理一下,尤其是 unsigned XXX 寫起來太難看了,可是這又帶來了問題——WinDef.h 把好聽的名字都占去了。然后,我只能在自己的命名空間下這樣來一番了:
xlDef.h |
#ifndef __XLDEF_H_44FDC6C3_12F1_4BF3_8F9F_1ABED755E8ED_INCLUDED__ #define __XLDEF_H_44FDC6C3_12F1_4BF3_8F9F_1ABED755E8ED_INCLUDED__
namespace xl { typedef char CHAR; typedef unsigned char UCHAR; typedef short SHORT; typedef unsigned short USHORT; typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; typedef long long LONGLONG; typedef unsigned long long ULONGLONG;
typedef void VOID; typedef bool BOOLEAN; typedef INT BOOL;
typedef UCHAR BYTE; typedef USHORT WORD; typedef ULONG DWORD; typedef ULONGLONG QWORD;
const BOOL TRUE = 1; const BOOL FALSE = 0; const VOID *NULL = 0;
typedef struct interface;
} // namespace xl
#endif // #ifndef __XLDEF_H_44FDC6C3_12F1_4BF3_8F9F_1ABED755E8ED_INCLUDED__ |
但是,問題是,當(dāng) using namespace xl 并 #include <Windows.h> 以后,隨手寫一個(gè)“DWORD”,就會(huì)有歧義了。如果用的時(shí)候要寫成 xl::DWORD,那還不如現(xiàn)在就命名成 XL_DWORD 好了……這點(diǎn)仍然在糾結(jié)中……路過朋友請(qǐng)給點(diǎn)意見:)
接下來是最基礎(chǔ)一層的組成。我想先把 Array、List、BinaryTree 給實(shí)現(xiàn)一下。然后第二層中利用 Array 實(shí)現(xiàn) String,利用 List 搞個(gè) Queue、Stack 什么的,利用 BinaryTree 搞個(gè) Map、Set 之類的。只是數(shù)據(jù)結(jié)構(gòu)中的“圖”,不知道怎么搞比較方便,如果可能,也可以在第一層實(shí)現(xiàn)掉。
不得不考慮的是 iterator 的問題。由于 STL 的 iterator 深入人心,我很想也搞個(gè)類似的支持。但是,STL 的 iterator 是可以跨容器的,也就是,可以在 list 的 insert 里填入 vector 的 iterator 作為參數(shù)。我不太了解 STL 的具體做法,但是粗看似乎是用模板實(shí)現(xiàn)的。可是這樣的話,就有一個(gè)很大的問題,這個(gè)模板參數(shù)將是沒有任何約束的,在明明需要 iterator 的參數(shù)的位置,我可以隨意填一個(gè)別的東西,直到有調(diào)用 iterator 的什么方法,編譯器才給出錯(cuò)誤。這樣,實(shí)際上在接口中沒法為使用者提供足夠的信息(或者說,提供語(yǔ)法上的約束)讓他明白這個(gè)參數(shù)應(yīng)該是什么。比較好的做法可能是 .Net 的那一套,定義接口 IEnumerator、IEnumerable 等等,然后各個(gè)類都去實(shí)現(xiàn)這個(gè)接口,迭代器也可以只針對(duì)接口編寫。但是由于 C++ 中的多態(tài)必須用指針表示,那么在參數(shù)、返回值(特別是返回值)中,指針的 delete 又給使用帶來了麻煩。于是,似乎需要先有一個(gè)完善的智能指針作為基礎(chǔ)才可以。而智能指針,如果要線程安全,又必須有平臺(tái)支持,所以似乎智能指針沒法放在這么基礎(chǔ)的位置。…………
繞了好久,也想了好久,始終還是找不到好的辦法。所以,我暫時(shí)覺得還是放棄跨容器的 iterator 了,其實(shí)說到底,這只是勉強(qiáng)制造的、看似來很精巧、其實(shí)不那么完美的東西而已。
Array、List、Tree 暫時(shí)設(shè)計(jì)如下:
xlArray.h |
#ifndef __XLARRAY_H_3B18D7E2_B52A_4D57_BE4B_657F9D17320D_INCLUDED__ #define __XLARRAY_H_3B18D7E2_B52A_4D57_BE4B_657F9D17320D_INCLUDED__
#include "xlDef.h"
namespace xl {
template <typename T> class Array { public: Array(); Array(const Array<T> &that); ~Array();
public: class Iterator { public: Iterator(); Iterator(const Array<T> *array); Iterator(Iterator &that);
private: array<T> *array; UINT current; BOOLEAN bof; BOOLEAN eof;
public: T &operator * (); T *operator -> ();
public: Iterator &operator = (Iterator &that); BOOLEAN operator == (Iterator &that); BOOLEAN operator != (Iterator &that);
public: Iterator operator ++ (); Iterator operator ++ (int); Iterator operator -- (); Iterator operator -- (int); };
public: Iterator Bof(); Iterator Begin(); Iterator End(); Iterator Eof();
public: Array<T> &operator=(const Array<T> &that); BOOLEAN operator==(const Array<T> &that) const; BOOLEAN operator!=(const Array<T> &that) const;
public: T &operator[](UINT index); const T &operator[](UINT index) const;
public: BOOLEAN Empty(); UINT Count();
public: VOID PushFront(const T &tValue); VOID PushBack(const T &tValue); VOID PopFront(); VOID PopBack(); VOID Insert(const Iterator &beforeWhich, const T &value); VOID Insert(const Iterator &beforeWhich, const Iterator &firstToInsert, const Iterator &NextOfLastToInsert); Iterator Delete(const Iterator &which); Iterator Delete(const Iterator &firstToDelete, const Iterator &nextOfLastToDelete); VOID SetValue(const Iterator &which, const T &value); VOID SetValue(const Iterator &firstToDelete, const Iterator &nextOfLastToDelete, const T &value);
private: T *m_pData; };
} // namespace xl
#endif // #ifndef __XLARRAY_H_3B18D7E2_B52A_4D57_BE4B_657F9D17320D_INCLUDED__ |
xlList.h |
#ifndef __XLLIST_H_2BEF1B3C_A056_4EC7_B5E3_9898E7945B54_INCLUDED__ #define __XLLIST_H_2BEF1B3C_A056_4EC7_B5E3_9898E7945B54_INCLUDED__
#include "xlDef.h"
namespace xl { template <typename T> class List { public: List(); List(const List<T> &that); ~List();
private: struct Node { T value; Node *prev; Node *next; };
public: class Iterator { public: Iterator(); Iterator(const List<T> *list); Iterator(Iterator &that);
private: List<T> *list; Node *current; BOOLEAN bof; BOOLEAN eof;
public: T &operator * (); T *operator -> ();
public: Iterator &operator = (Iterator &that); BOOLEAN operator == (Iterator &that); BOOLEAN operator != (Iterator &that);
public: Iterator operator ++ (); Iterator operator ++ (int); Iterator operator -- (); Iterator operator -- (int); };
public: Iterator Bof(); Iterator Begin(); Iterator End(); Iterator Eof();
public: List<T> &operator=(const List<T> &that); BOOLEAN operator==(const List<T> &that) const; BOOLEAN operator!=(const List<T> &that) const;
public: BOOLEAN Empty(); UINT Count();
public: VOID PushFront(const T &tValue); VOID PushBack(const T &tValue); VOID PopFront(); VOID PopBack(); VOID Insert(const Iterator &beforeWhich, const T &value); VOID Insert(const Iterator &beforeWhich, const Iterator &firstToInsert, const Iterator &NextOfLastToInsert); Iterator Delete(const Iterator &which); Iterator Delete(const Iterator &firstToDelete, const Iterator &nextOfLastToDelete);
public: Node *head; Node *tail; };
} // namespace xl
#endif // #ifndef __XLLIST_H_2BEF1B3C_A056_4EC7_B5E3_9898E7945B54_INCLUDED__
|
xlTree.h |
#ifndef __XLTREE_H_6BB48AA6_133A_4E9F_944E_504B887B6980_INCLUDED__ #define __XLTREE_H_6BB48AA6_133A_4E9F_944E_504B887B6980_INCLUDED__
#include "xlDef.h"
namespace xl { template <typename T> class Tree { public: Tree(); Tree(const Tree<T> &that); ~Tree();
private: struct Node { T value; Node *parent; Node *left; Node *right; };
private: class Iterator { public: Iterator(); Iterator(const Tree<T> *tree); Iterator(Iterator &that);
private: Tree<T> *tree; Node *current; BOOLEAN bof; BOOLEAN eof;
public: T &operator * (); T *operator -> ();
public: Iterator &operator = (Iterator &that); BOOLEAN operator == (Iterator &that); BOOLEAN operator != (Iterator &that);
public: Iterator Parent(); Iterator Left(); Iterator Right(); };
class PreorderIterator : public Iterator { public: Iterator operator ++ (); Iterator operator ++ (int); Iterator operator -- (); Iterator operator -- (int); };
class InorderIterator : public Iterator { public: Iterator operator ++ (); Iterator operator ++ (int); Iterator operator -- (); Iterator operator -- (int); };
class PostorderIterator : public Iterator { public: Iterator operator ++ (); Iterator operator ++ (int); Iterator operator -- (); Iterator operator -- (int); };
public: Iterator Bof(); Iterator Begin(); Iterator Eof();
public: Tree<T> &operator=(const Tree<T> &that); BOOLEAN operator==(const Tree<T> &that) const; BOOLEAN operator!=(const Tree<T> &that) const;
public: BOOLEAN Empty(); UINT Count();
public: VOID InsertLeft(const Iterator &beforeWhich, const T &value); VOID InsertRight(const Iterator &beforeWhich, const T &value ); Iterator Delete(const Iterator &which);
public: Node *head; };
} // namespace xl
#endif // #ifndef __XLTREE_H_6BB48AA6_133A_4E9F_944E_504B887B6980_INCLUDED__
|
(Tree 的接口還沒完全考慮好,也不知道有沒有必要把 Node 獨(dú)立出來。)
這樣是否大概足夠了?敬請(qǐng)大家指教~
(再次重申一下,請(qǐng)不要來留個(gè)言說“干嗎要重新發(fā)明輪子?”、“XXX 不是很好用嗎?”之類的,謝謝!歡迎志同道合的朋友探討,如能為我解惑,那么非常感謝。)
posted on 2009-09-26 17:43
溪流 閱讀(664)
評(píng)論(18) 編輯 收藏 引用 所屬分類:
C++