青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-90  評(píng)論-947  文章-0  trackbacks-0

打算先把基礎(chǔ)的東西組織起來(lái),作為一個(gè)“大庫(kù)”(見上一篇《小庫(kù)還是大庫(kù)?》)。然后填加各個(gè)實(shí)用功能,作為一個(gè)個(gè)小庫(kù)或者大庫(kù),過(guò)段時(shí)間再想辦法組織整理了。

首先是類型系統(tǒng),我想來(lái)想去,覺得還是必須整理一下,尤其是 unsigned XXX 寫起來(lái)太難看了,可是這又帶來(lái)了問(wèn)題——WinDef.h 把好聽的名字都占去了。然后,我只能在自己的命名空間下這樣來(lái)一番了:

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__

但是,問(wèn)題是,當(dāng) using namespace xl 并 #include <Windows.h> 以后,隨手寫一個(gè)“DWORD”,就會(huì)有歧義了。如果用的時(shí)候要寫成 xl::DWORD,那還不如現(xiàn)在就命名成 XL_DWORD 好了……這點(diǎn)仍然在糾結(jié)中……路過(guò)朋友請(qǐng)給點(diǎn)意見:)

接下來(lái)是最基礎(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 的問(wèn)題。由于 STL 的 iterator 深入人心,我很想也搞個(gè)類似的支持。但是,STL 的 iterator 是可以跨容器的,也就是,可以在 list 的 insert 里填入 vector 的 iterator 作為參數(shù)。我不太了解 STL 的具體做法,但是粗看似乎是用模板實(shí)現(xiàn)的??墒沁@樣的話,就有一個(gè)很大的問(wèn)題,這個(gè)模板參數(shù)將是沒(méi)有任何約束的,在明明需要 iterator 的參數(shù)的位置,我可以隨意填一個(gè)別的東西,直到有調(diào)用 iterator 的什么方法,編譯器才給出錯(cuò)誤。這樣,實(shí)際上在接口中沒(méi)法為使用者提供足夠的信息(或者說(shuō),提供語(yǔ)法上的約束)讓他明白這個(gè)參數(shù)應(yīng)該是什么。比較好的做法可能是 .Net 的那一套,定義接口 IEnumerator、IEnumerable 等等,然后各個(gè)類都去實(shí)現(xiàn)這個(gè)接口,迭代器也可以只針對(duì)接口編寫。但是由于 C++ 中的多態(tài)必須用指針表示,那么在參數(shù)、返回值(特別是返回值)中,指針的 delete 又給使用帶來(lái)了麻煩。于是,似乎需要先有一個(gè)完善的智能指針作為基礎(chǔ)才可以。而智能指針,如果要線程安全,又必須有平臺(tái)支持,所以似乎智能指針沒(méi)法放在這么基礎(chǔ)的位置?!?/p>

繞了好久,也想了好久,始終還是找不到好的辦法。所以,我暫時(shí)覺得還是放棄跨容器的 iterator 了,其實(shí)說(shuō)到底,這只是勉強(qiáng)制造的、看似來(lái)很精巧、其實(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 的接口還沒(méi)完全考慮好,也不知道有沒(méi)有必要把 Node 獨(dú)立出來(lái)。)

這樣是否大概足夠了?敬請(qǐng)大家指教~

(再次重申一下,請(qǐng)不要來(lái)留個(gè)言說(shuō)“干嗎要重新發(fā)明輪子?”、“XXX 不是很好用嗎?”之類的,謝謝!歡迎志同道合的朋友探討,如能為我解惑,那么非常感謝。)

posted on 2009-09-26 17:43 溪流 閱讀(679) 評(píng)論(18)  編輯 收藏 引用 所屬分類: C++

評(píng)論:
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 12:46 | 陳梓瀚(vczh)
碰巧我也再造輪子。我吸取了stl和.net的經(jīng)驗(yàn)做了一套collection出來(lái),linq也實(shí)現(xiàn)了,string也實(shí)現(xiàn)了。現(xiàn)在正在做stream,還有無(wú)縫支持自定義的用戶類型。這就有4套子系統(tǒng)了,其中自反連接和兩兩互轉(zhuǎn)一共需要15個(gè)運(yùn)算器(包括regex啦,linq啦,自定義語(yǔ)法分析器什么的)。

因?yàn)槲沂亲鼍幾g器的所以對(duì)復(fù)雜數(shù)據(jù)結(jié)構(gòu)的靈活運(yùn)算要求非常高,但是效率并沒(méi)有太苛求。完了我們可以交流一下。  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 12:55 | 陳梓瀚(vczh)
然后我跟你說(shuō)說(shuō)VL++2.0的一些故事……現(xiàn)在已經(jīng)推翻掉寫3.0了,其中的一些決定就是
1:不再typedef基礎(chǔ)類型
2:不再加前綴
3:大規(guī)模利用模板
4:加強(qiáng)各個(gè)模塊之間的關(guān)系,互操作性要變得很強(qiáng)

你可以考慮不走我的老路……  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 12:58 | 陳梓瀚(vczh)
于是最后提示一點(diǎn),根據(jù)我前面幾年造輪子的實(shí)踐,獨(dú)立二叉樹的接口一點(diǎn)意義都沒(méi)有……  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 15:49 | 溪流
@陳梓瀚(vczh)

陳老師你好,我一年多前實(shí)習(xí)的時(shí)候因?yàn)楣静辉试S使用STL、MFC等等所有流行的庫(kù),叫我們“用到的數(shù)據(jù)結(jié)構(gòu)自己寫”。當(dāng)時(shí)只寫了個(gè) Vector、String,足以應(yīng)付任務(wù)了。不過(guò)我就是從那時(shí)開始明白寫庫(kù)的意義,以及感受到用自己的庫(kù)的那種爽快的感覺的。

很佩服你的技術(shù),粗看過(guò)你的代碼,我知道你把基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)全部實(shí)現(xiàn)了一遍,甚至regex,以及在代碼里寫 EBNF,等等。(我第一篇日志的開頭語(yǔ)不知道您看過(guò)了沒(méi),呵呵)

我也想不走老路,不過(guò)有些東西可能不走一遍不會(huì)明白,所以我想可能先自然一點(diǎn),到第二遍、第三遍再來(lái)總結(jié)以及回避已知問(wèn)題。關(guān)于你說(shuō)的4點(diǎn),我比較想了解原因以及大概做法,可否稍微解釋下?特別是1和2,這個(gè)是現(xiàn)在就擺在我面前的。然后是3、4,我可以聽一聽,雖然可能不是馬上體會(huì)得到。  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 15:51 | 溪流
@陳梓瀚(vczh)

你的意思是說(shuō) Tree::Node 沒(méi)必要暴露出來(lái)嗎?再問(wèn)一下問(wèn)一下,你覺得基礎(chǔ)庫(kù)里有必要存在二叉樹這種結(jié)構(gòu)嗎?還有沒(méi)有必要以及可能包含圖的結(jié)構(gòu)呢?  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 18:00 | OwnWaterloo
@溪流
1. 如非必要,不typedef基礎(chǔ)類型

為什么要typedef?
typedef是為了提供語(yǔ)意。

DWORD, WORD, BYTE的語(yǔ)意是固定長(zhǎng)度整數(shù)。
stdint.h, cstdint, sys/stdin.h, windows.h 中已經(jīng)有這樣的功能, 就盡可能去復(fù)用。
自己省事 —— 你有精力去為不同平臺(tái)定義出對(duì)應(yīng)的DWORD, WORD, BYTE嗎?
既然上面的幾個(gè)文件中已經(jīng)給出了這種功能, 并且在各個(gè)平臺(tái)下都測(cè)試過(guò), 為什么不直接使用呢?

別人也省事。
需要明白一點(diǎn):用戶與其依賴的庫(kù)通常不是線性結(jié)構(gòu),而是樹形結(jié)構(gòu)。
A庫(kù)為了可移植性的去typedef DWORD, WORD, BYTE,
B庫(kù)也為了可移植性去typedef DWORD, WORD, BYTE,
一個(gè)客戶C, 同時(shí)需要A、B, 他該用哪個(gè)庫(kù)的DWORD?
這種作法是徒增不必要的概念。


對(duì)自己庫(kù)獨(dú)有, 并有可能改變的概念, 才可以考慮使用typedef 來(lái)建立一個(gè)語(yǔ)意。
比如time.h中的time_t, clock_t, 代表了兩個(gè)獨(dú)立的概念。
  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 18:10 | OwnWaterloo
@溪流
2:不再加前綴

其實(shí)vczh同學(xué)放出來(lái)的代碼中的VL_前綴……
我覺得看上去是很傷眼的……
當(dāng)然, 這是口味問(wèn)題。


關(guān)于這個(gè)問(wèn)題:
"但是,問(wèn)題是,當(dāng) using namespace xl 并 #include <Windows.h> 以后,隨手寫一個(gè)“DWORD”,就會(huì)有歧義了。如果用的時(shí)候要寫成 xl::DWORD,那還不如現(xiàn)在就命名成 XL_DWORD 好了"

首先, 不必定義xl::DWORD。
對(duì)于其他情況, 名字空間相對(duì)于前綴是有一些優(yōu)勢(shì)的。
1. 如果存在歧義, 無(wú)論是名字空間,還是前綴, 都必須使用全稱。
2. 不存在歧義的時(shí)候, 名字空間可以打開, 可以別名。 而前綴必須時(shí)刻都帶著, 永遠(yuǎn)逃不掉。
3. 如果不小心, 兩個(gè)使用前綴的庫(kù)都出現(xiàn)了相同名字, 前綴技術(shù)就很麻煩。
A庫(kù)是個(gè)做網(wǎng)絡(luò)的, 有一個(gè) net_f,
B庫(kù)也是個(gè)做網(wǎng)絡(luò)的, 依然一個(gè) net_f,
要同時(shí)使用兩個(gè)庫(kù), 就需要自己去寫轉(zhuǎn)發(fā)函數(shù)。

而名字空間, 可以一開始就很長(zhǎng)。
namespace net_byA { void f() }
namespace net_byB { void f() }


只使用A(或B)的用戶,就可以使用別名:
namepsace net = net_byA(B);
net::f;

如果同時(shí)使用A、B的用戶, 只好:
net_byA::f;
net_byB::f;

也比自己寫轉(zhuǎn)發(fā)函數(shù)要強(qiáng)。

總之, 名字空間是一種更靈活的方式。

如果決定使用C++編寫庫(kù), 而且不考慮過(guò)分古董的編譯器, 就應(yīng)該選用名字空間。  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 18:26 | OwnWaterloo
@溪流

各種現(xiàn)有的流行的庫(kù)中, 實(shí)現(xiàn)了侵入式容器的比較少。
大都是非侵入式容器。

侵入式容器我只在如下一些庫(kù)中見到過(guò):
linux/list.h, linux/rbtree.h
sourceforge有個(gè)叫l(wèi)ibaasdl的項(xiàng)目,有一個(gè)GDST(generic data-structure template)子庫(kù)中的一些是侵入式的(還有一些我沒(méi)看完)

SGI-STL中4種關(guān)聯(lián)容器底層使用的是同一種容器,_Rb_tree。
它是非侵入式的。
但是構(gòu)建它的_Rb_tree_base、_Rb_tree_base_iterator都是非侵入式的。
SGI-STL沒(méi)有構(gòu)建出一個(gè)侵入式的RbTree層, 而是直接使用侵入式的_Rb_tree_base,和_Rb_tree_base_iterator構(gòu)建出了非侵入式的_Rb_tree。
稍微有點(diǎn)可惜。
不過(guò)即使有一個(gè)侵入式的RbTree, SGI-STL也是不會(huì)將其公開出來(lái)的。


如果想練手, 可以考慮構(gòu)建一套侵入式的容器, 比僅僅重復(fù)STL中的東西來(lái)得有意義。

還有, STL中沒(méi)有樹式的堆。
heap相關(guān)的那幾個(gè)函數(shù)都是對(duì)random_access的線性表使用的。
也可以考慮在這里做做文章。  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 18:51 | OwnWaterloo
const VOID *NULL = 0;
在C++中, 這樣定義NULL是行不通的。
 
普遍的做法是直接使用0,或者stddef.h, cstddef 中的NULL宏:
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0) /* 這是C中的做法 */
#endif
 
void* 在C中可以隱式轉(zhuǎn)換到其他類型指針。
但C++不行。
 
 
或者, 更激進(jìn)一點(diǎn), 使用nullptr:
nullptr
因?yàn)镃++0x將引入nullptr作為關(guān)鍵字。
使用nullptr,算是"向前兼容"吧…… 等轉(zhuǎn)到C++0x時(shí),就可以直接使用真正的nullptr了。
 
上面最后一種nullptr和C++0x中的語(yǔ)意最相似, 不過(guò)不一定能在所有編譯器中都通過(guò)。
至少要支持成員函數(shù)模板才行。
如果不支持匿名類可以改用別的方式實(shí)現(xiàn)。
 
 
 
 typedef struct interface;
這是什么語(yǔ)法?
這也是徒增概念的地方。
 
C++程序員如果不知道下面的代碼是一個(gè)interface
struct Ixxx {
    virtual ~Ixxx();
    virtual ...
};
 
將struct 換成interface對(duì)他的幫助也不大。
  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 19:10 | OwnWaterloo
不叫"跨容器"的iterator。
而是iterator符合特定的concepts。
不過(guò)你說(shuō)對(duì)了, 它確實(shí)和模板有關(guān)。
 
比如,使用一對(duì)forwarding_iterator構(gòu)造vector的偽代碼:
concepts
 
vector有一個(gè)構(gòu)造函數(shù)模板。
只要FotIt 滿足forwarding_iterator的概念,上面的構(gòu)造函數(shù)就可以生成。
forwarding_iterator 要支持(但不限于)++, *, 因?yàn)樯厦娴拇a使用了這2個(gè)操作符。
vector的實(shí)現(xiàn)也不會(huì)是上面那樣, 不會(huì)調(diào)用new 去默認(rèn)構(gòu)造一次。
會(huì)使用其allocator來(lái)分配,并使用uninitialized_copy。
不過(guò)那樣就看不到vector() 對(duì)forwarding_iterator的要求了。
 
 
這是C++中的方式,GP的,基于concepts的方式。C#中可是沒(méi)得這么爽的哦。
并且, GP的、基于concepts的方式, 也可以退化成OOP的,基于interface的方式。
反之不行, 因?yàn)閏oncepts的偶和性更低。
 
 
不僅僅是容器。 整個(gè)STL中的組件都是通過(guò)concepts來(lái)協(xié)作而非interface。
如果你喜歡struct Iterator的方式, 或者IComparable , 也可以這么搞一套。
代碼不會(huì)比GP來(lái)得少, 效率不會(huì)比GP來(lái)得高, 也不會(huì)比GP靈活 —— GP可以退化為基于interface, 反之不行。
 
  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 19:10 | OwnWaterloo
上面貼的代碼有問(wèn)題, 重新貼一下……
 
template<typename T,  >
class vector {
    T
* first_;
    T
* last_;
public:
    template
<class ForIt>
    vector(ForIt first,ForIt last) {
        difference_type d 
= distance(first,last);
        first_ 
= new T[ d + padding ];
        last_ 
= first_ + d;
        
for (T* p = first;first!=last;++first,++p)
            
*= *first;
    }
};
  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 20:33 | 溪流
@OwnWaterloo

先謝過(guò)您的這么詳細(xì)的指點(diǎn)。等我仔細(xì)看過(guò)后再來(lái)提后續(xù)問(wèn)題:)  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 22:35 | 溪流
@OwnWaterloo

1、關(guān)于 typedef

第一,我想我要寫的庫(kù)要保持獨(dú)立性。如果去包含了 Winows.h 了,那么就失去了這一部分的獨(dú)立性了。在做容器方面的東西的時(shí)候,實(shí)際上我根本不會(huì)用到 Windwos API,而這一 include,增加無(wú)畏的依賴的同時(shí),還把平臺(tái)陷死了(雖然我不準(zhǔn)備搞多么跨平臺(tái)的東西,但是明明可以不依賴的,還是不要去依賴,是嗎?)

我想,庫(kù)的用戶可能不需要去寫太多次 a::DWORD、b::DWORD,只要他們的定義是兼容的,傳入的值就可以用。

其實(shí)我最頭痛的就是 Windows.h 把這些名字都占去了,而且是全局的,是的用戶無(wú)法簡(jiǎn)單地寫一個(gè) DWORD 來(lái)定義 Windows.h 中的 DWORD 了。我知道加前綴不是好的解決方案,可是還有其他一套如此通用的名字嗎?
  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 22:45 | OwnWaterloo
@溪流
用stdint.h。 把這個(gè)棘手的工作交給編譯器提供商。
并且, 你實(shí)現(xiàn)容器庫(kù)的時(shí)候, 需要DWORD么……


> 只要他們的定義是兼容的,傳入的值就可以用。
你要去檢查。 是否每個(gè)庫(kù)都是兼容的。

另一種方式是只依賴于一處定義。比如stdint.h


msvc沒(méi)有提供stdint.h, 因?yàn)樗恢С諧99。
網(wǎng)上有一個(gè)stdint.h for msvc, 使用BSD3條款的許可證。

或者自己寫:

msvc 提供了 __intN擴(kuò)展。
所以 intN_t uintN_t 很好處理
int_leastN_t, 這個(gè)本來(lái)就不能假設(shè)它的寬度, 按字面來(lái)即可。

uintptr_t, intptr_t 可以包含basetsd.h
typedef INT_PTR intptr_t;
typedef UINT_PTR uintptr_t;


現(xiàn)在你代碼中依賴的就是:
(u)intN_t, (u)int_fastN_t ,, (u)intptr_t, (u)intmax_t 等等。  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-27 23:58 | 溪流
@OwnWaterloo

是的,現(xiàn)在是用不著 DWORD,但是以后一些功能庫(kù)會(huì)用到。
stdint.h 中的類型名稱似乎也不怎么干凈利索。
要不就直接用標(biāo)準(zhǔn)名稱好了?只是我很不喜歡 unsigned int, size_t 這種寫法。  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-28 00:17 | OwnWaterloo
@溪流
這個(gè)…… 其實(shí)是個(gè)口味問(wèn)題 …… all fine.
我比較懶…… 有現(xiàn)成的就喜歡用現(xiàn)成的…… so ……

  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-28 00:27 | 溪流
@OwnWaterloo

打算這樣,如何?

namespace xl
{
    typedef unsigned 
char uchar;
    typedef unsigned 
short ushort;
    typedef unsigned 
int uint;
    typedef unsigned 
long ulong;
    typedef 
long long longlong;
    typedef unsigned 
long long ulonglong;

    typedef wchar_t wchar;
    typedef unsigned wchar uwchar;

    typedef __int8 int8;
    typedef __int16 int16;
    typedef __int32 int32;
    typedef __int64 int64;

    typedef unsigned int8 uint8;
    typedef unsigned int16 uint16;
    typedef unsigned int32 uint32;
    typedef unsigned int64 uint64;

    
struct
    
{
        template
<typename T>
        
operator T*() const
        
{
            
return 0;
        }


    }
 nullptr;

}
 // namespace xl


我的目的主要是為了書寫簡(jiǎn)潔,其他的其實(shí)對(duì)我來(lái)說(shuō)關(guān)系不大,暫時(shí)主要考慮 Win + MSVC 平臺(tái)。nullptr 的定義真的好精妙!
  回復(fù)  更多評(píng)論
  
# re: 開始把庫(kù)搞起來(lái)了 2009-09-28 00:40 | OwnWaterloo
@溪流
nullptr是《eff cpp》中提到的。

對(duì)于int和指針的重載:
void f(int );
void f(void* );

f(0); // f(int );
f(NULL); // 如果是stddef.h 中的NULL, f(int );
f(nullptr); // 書中提到的那個(gè)nullptr, 會(huì)選中 f(void* );

如果還有另一種指針:

void f(int* ); nullptr 會(huì)引起歧義。

當(dāng)然, 最好是避免這種重載……

  回復(fù)  更多評(píng)論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲人成在线播放| 欧美日本一区二区视频在线观看| 国产欧美日韩在线视频| 久久夜精品va视频免费观看| 亚洲特级毛片| 999在线观看精品免费不卡网站| 欧美激情1区| 欧美wwwwww| 亚洲激情女人| 亚洲美女av黄| 亚洲深爱激情| 午夜国产一区| 久久久久久亚洲精品中文字幕 | 亚洲成色777777女色窝| 欧美不卡高清| 亚洲日本成人| 国产精品99久久久久久久vr| 9久re热视频在线精品| 一本色道久久加勒比88综合| 亚洲性av在线| 久久不射中文字幕| 欧美高清在线观看| 国产精品青草久久| 国产字幕视频一区二区| 亚洲欧美国产精品桃花 | 欧美成年人网站| 欧美欧美天天天天操| 欧美日韩精品在线视频| 国产精品电影观看| 一区免费在线| 亚洲最新在线视频| 久久久久久电影| 亚洲精品久久久久久久久久久久| 亚洲综合视频网| 美女性感视频久久久| 国产欧美亚洲一区| 亚洲一区二区在线观看视频| 欧美国产日韩亚洲一区| 国产精品区一区二区三区| 一色屋精品视频在线看| 亚洲综合日韩在线| 欧美国产一区在线| 午夜精品久久| 欧美伦理91| 精品成人一区二区| 欧美在线免费视频| 日韩午夜电影| 久久婷婷蜜乳一本欲蜜臀| 欧美日韩美女| 最新日韩在线视频| 美女脱光内衣内裤视频久久网站| 欧美激情一区二区三级高清视频| 最新国产乱人伦偷精品免费网站| 9i看片成人免费高清| 欧美一区三区三区高中清蜜桃| 欧美日韩精品久久| 亚洲区一区二| 久久中文字幕一区二区三区| 亚洲在线一区二区三区| 欧美日韩国产美| 亚洲国产cao| 久热精品视频在线观看一区| 亚洲一区二区三区激情| 欧美久久影院| 亚洲国产二区| 老司机一区二区三区| 亚洲欧美在线观看| 国产精品视频一二三| 香蕉乱码成人久久天堂爱免费| av成人免费观看| 欧美日在线观看| 一本一本久久a久久精品综合麻豆| 亚洲国产合集| 欧美二区不卡| 亚洲精品视频免费| 亚洲黄色在线视频| 欧美日韩免费高清| 亚洲视频免费观看| 在线综合+亚洲+欧美中文字幕| 免费观看30秒视频久久| 亚洲精品社区| 一区二区三区久久| 国产农村妇女精品一区二区| 久久国产精品高清| 久久成人在线| 最新日韩中文字幕| 99热免费精品在线观看| 欧美图区在线视频| 欧美一区二区三区啪啪| 亚洲欧美国产另类| 狠色狠色综合久久| 亚洲成色最大综合在线| 欧美国产日韩一区二区| 亚洲一区在线直播| 欧美在线观看视频| 亚洲激情av| 国内外成人免费激情在线视频 | 免费观看成人| 欧美极品一区| 欧美影院久久久| 美日韩精品免费| 亚洲欧美另类中文字幕| 亚洲欧美日韩直播| 91久久精品国产91久久性色| 亚洲国产精品黑人久久久| 国产精品久久久久一区| 男人的天堂亚洲| 欧美天天在线| 欧美成人一区在线| 国产精品夜夜夜| 亚洲黄色免费电影| 亚洲欧洲日产国产综合网| 欧美成人在线影院| 国产精品久久久久久福利一牛影视 | 免费成人在线观看视频| 欧美日韩精品是欧美日韩精品| 欧美一级电影久久| 欧美成人高清| 久久亚洲捆绑美女| 欧美日韩在线视频首页| 久久一区中文字幕| 欧美三级中文字幕在线观看| 欧美在线不卡视频| 欧美日韩国产丝袜另类| 久久精品人人爽| 欧美日韩国产不卡| 亚洲国产高潮在线观看| 国产乱子伦一区二区三区国色天香| 欧美一区二区三区四区视频| 免费久久99精品国产| 亚洲男女毛片无遮挡| 麻豆精品视频在线观看| 狂野欧美激情性xxxx| 欧美日韩亚洲一区| 欧美日韩性视频在线| 久久综合九色综合欧美狠狠| 国产精品露脸自拍| 91久久久久久久久| 国产主播在线一区| 亚洲欧美日韩精品| 亚洲欧美日韩综合aⅴ视频| 欧美粗暴jizz性欧美20| 久久精品99国产精品日本| 欧美日韩亚洲一区| 亚洲精品中文在线| 亚洲精品视频中文字幕| 欧美亚洲综合另类| 欧美一区1区三区3区公司| 欧美女人交a| 亚洲欧洲一区二区三区久久| 国产乱人伦精品一区二区| 亚洲欧美自拍偷拍| 久久久久一区二区三区| 国产一区二区三区四区五区美女| 亚洲欧美日韩中文视频| 性欧美大战久久久久久久免费观看 | 亚洲精品在线观| 一区二区三区日韩精品| 欧美视频国产精品| 亚洲欧美日本视频在线观看| 亚洲一区三区在线观看| 欧美视频免费| 亚洲欧美日韩国产综合| 欧美成人资源| 亚洲日本电影| 国产精品一二三四区| 久久久久88色偷偷免费| 亚洲精品1234| 亚洲国产精品久久精品怡红院| 久久人人爽人人爽| 国产精品一卡二卡| 久久婷婷国产综合精品青草| 最新成人在线| 欧美在线综合| 亚洲欧洲一区二区三区久久| 国产精品久久久久婷婷| 免费亚洲电影在线| 亚洲欧美中文字幕| 亚洲人成在线观看| 久久久综合视频| 中国av一区| 亚洲国产岛国毛片在线| 国产欧美日韩视频| 欧美精品一区视频| 久久精品国产久精国产思思 | 亚洲欧洲三级| 亚洲一区二区久久| 在线日韩日本国产亚洲| 欧美性色aⅴ视频一区日韩精品| 亚洲欧美日本在线| 卡通动漫国产精品| 亚洲精品久久久久久久久久久久久 | 模特精品在线| 欧美福利视频一区| 亚洲人成艺术| 欧美巨乳在线| 99国产一区| 在线综合视频| 国产精品久久久久久久久免费樱桃| 久久精彩视频|