泛型編程與設計新思維
作者:徐景周


template<class T1, int Size>class Queue // 類(lèi)模板,其中T1為類(lèi)型參數,Size為非類(lèi)型參數{ public: explicit Queue():size_(Size){}; // 顯式構造,避免隱式轉換 …… template<class T2> void assign(T2 first,T2 last); // 內嵌函數模板 private: T* temp_; int size_;} // 類(lèi)模板中內嵌函數模板Compare的外圍實(shí)現(如在Queue類(lèi)外實(shí)現) template<class T1,int Size> template<class T2> void Queue<T1,Size>::assign (T2 first,T2 last) {}; // 模板的使用方法 int ia[4] = {0,1,2,3}; Queue<int, sizeof(ia)/sizeof(int)> qi; qi.assign(ai,ai+4);
template<class InputIterator, class Distance> void advance(InputIterator& i, Distance n, input_iterator_tag) { for(; n>0; --n,++i){} // InputIterator具有++性 }2、ForwardIterator template<class ForwardIterator, class Distance> void advance(ForwardIterator& i, Distance n,forward_iterator_tag) { advance(i, n, input_iterator_tag()); }3、BidirectionalIterator template<class BidirectionalIterator, class Distance> void advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag) { if(n>=0) // 具有++、--性 for(; n>0; --n,++i){} else for(; n>0; ++n,--i){} }4、RandomAccessIterator template<class RandomAccessIterator, class Distance> void advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag) { i += n; // 具有++、--、+=等性 } 函數對象(Function object)也稱(chēng)仿函數(Functor),是一種能以一般函數調用語(yǔ)法來(lái)調用的對象,函數指針(Function pointer)是一種函數對象,所有具有operator()操作符重載的成員函數也是函數對象。函數對象一般分為無(wú)參函數(Generator),單參函數(Unary Function)和雙參函數(Binary Function)三種形式,它們分別能以f()、f(x)和f(x,y)的形式被調用,STL定義的其他所有函數對象都是這三種概念的強化。如下簡(jiǎn)單示例展示幾種形式的實(shí)現: struct counter { typedef int result_type; counter(result_type init=0):n(init){} result_type operator() { return n++;} result_type n; }2、單參(Unary Function)形式 template<class Number> struct even // 函數對象even,找出第一個(gè)偶數 { bool operator()(Number x) const {return (x&1) == 0;} } // 使用算法find_if在區間A到A+N中找到滿(mǎn)足函數對象even的元素 int A[] = {1,0,3,4}; const int N=sizeof(A)/sizeof(int); find_if(A,A+N, even<int>());3、雙參(Binary Function)形式 struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1<s2) < 0;} }; // 使用函數對象ltstr,輸出set容器中A和B的并集 const int N=3 const char* a[N] = {"xjz","xzh","gh"}; const char* b[N]= {"jzx","zhx","abc"}; set<const char*,ltstr> A(a,a+N); set<const char*,ltstr> B(b,b+N); set_union(A.begin(),A.end(),B.begin(),B.end(), ostream_iterator<const char*>(cout," "), ltstr()); 容器(container)是一種對象(object),可以包含并管理其它的對象,并提供迭代器(iterators)用以定址其所包含之元素。根據迭代器種類(lèi)的不同,容器也分為幾中,以Input Iterator為迭代器的一般container,以Forward Iterator為迭代器的Forward Container,以Bidirectional Iterator 為迭代器的Reversible Container,以Random Access Iterator為迭代器的Random Access Container。STL定義二種大小可變的容器:序列式容器(Sequence Container)和關(guān)聯(lián)式容器(Associative Container)序列式容器包括vector、list和deque,關(guān)聯(lián)式容器包括set、map、multiset和multimap。以下示例簡(jiǎn)單說(shuō)明部分容器的使用:1、vector使用 // 將A中以元素5為分割點(diǎn),分別排序,使排序后5后面的元素都大于5之前的元素(后區間不排序), // 然后輸出int main() { int A[] = {7,2,6,4,5,8,9,3,1}; const int N=sizeof(A)/sizeof(int); vector<int> V(A,A+N); partial_sort(V,V+5,V+N); copy(V,V+N,ostream_iterator<int>(cout," ")); cout << endl; } 輸出可能是:1 2 3 4 5 8 9 7 62、list使用 // 產(chǎn)生一空l(shuí)ist,插入元素后排序,然后輸出 int main() { list<int> L1; L1.push_back(0); L1.push_front(1); L1.insert(++L1.begin,3); L1.sort(); copy(L1.begin(),L1.end(),ostream_iterator<int>(cout," ")); } 輸出:0 1 33、deque使用 int main() { deque<int> Q; Q.push_back(3); Q.push_front(1); Q.insert(Q.begin()+1,2); Copy(Q.begin(),Q.end(),ostream_iterator<int>(cout," ")); } 輸出:1 2 34、map使用 int main() { map<string,int> M; M.insert(make_pair("A",11); pair<map<string,int>::iterator, bool> p = M.insert(make_pair("C",5)); if(p.second) cout << p.first->second<<endl; } 輸出:55、multiset使用 int main() { const int N = 5; int a[N] = {4,1,1,3,5}; multiset<int> A(a,a+N); copy(A.begin(),A.end(),ostream_iterator<int>(cout," ")); } 輸出:1 1 3 4 5
// Singleton.h文件中class Singleton{public:static Singleton& Instance(){ if(!pInstance_){ if(destroyed_){ // 引用是否已經(jīng)失效 OnDeadReference(); } else { Create(); // 第一次時(shí)創(chuàng )建實(shí)例 } } return *pInstance_;}private: Singleton(); // 禁止默認構造 Singleton(const Singleton&); // 禁止拷貝構造 Singleton& operator= (const Singleton&); // 禁止賦值操作 static void Create() // 傳加創(chuàng )建的實(shí)例引用 { static Singleton theInstance; pInstance_ = &theInstance; } static void OnDeadReference() { throw std::runtime_error(" 實(shí)例被不正當消毀"); } virtual ~Singleton() { pInstance- = 0; destroyed_ = true; } static Singleton *pInstance_; static bool destroyed_;}// Singleton.cpp中靜態(tài)成員變量初始化Singleton* Singleton::pInstance_ = 0;Bool Singleton::destroyed_ = false; 如上所示,Singleton模式實(shí)現中只有一個(gè)public成員Instance()用來(lái)第一次使用時(shí)創(chuàng )建單一實(shí)例,當第二次使用時(shí)靜態(tài)變量將已經(jīng)被設定好,不會(huì )再次創(chuàng )建實(shí)例。還將默認構造函數、拷貝構造函數和賦值操作符放在private中,目地是不讓用戶(hù)使用它們。另外,為避免實(shí)例意外消毀后再實(shí)例化情況,加入靜態(tài)布爾變量destroy_來(lái)進(jìn)行判斷是否出錯,從而達到穩定性。 template < class T, template<class> calss CreationPolicy = CreateUsingNew, template<class> class LifetimePolicy=DefaultLifetime, > classs SingletonHolder { public: static T& Instance() { if(!pInstance_) { if(destroyed_) { LifetimePolicy<T>::OnDeadReference(); destroyed_ = false; } pInstance_ = CreationPolicy<T>::Create(); LifetimePolicy<T>::SchedultCall(&DestorySingleton); } return *pInstance_; } private: static void DestroySinleton() { assert(!destroyed_); CreationPlicy<T>::Destroy(pInstance_); pInstance_ = 0; destroyed_ = true; } SingletonHolder(); SingletonHolder (const SingletonHolder &); SingletonHolder & operator= (const SingletonHolder &); Static T* pInstance_; Static bool destroyed_; }; Instance()是SingletonHolder開(kāi)放的唯一一個(gè)public函數,它在CreationPolicy、LifetimePolicy中打造了一層外殼。其中模板參數類(lèi)型T,接收類(lèi)名,既需要進(jìn)行Singleton的類(lèi)。模板參數內的類(lèi)模板缺省參數CreateUsingNew是指通過(guò)new操作符和默認構造函數來(lái)產(chǎn)生對象,DefaultLifetime是通過(guò)C++規則來(lái)管理生命期。LifetimePolicy<T>中有二個(gè)成員函數,ScheduleDestrution()函數接受一個(gè)函數指針,指向析構操作的實(shí)際執行函數,如上面DestorySingleton析構函數;OnDeadReference()函數同上面一般C++中同名函數相同,是負責發(fā)現失效實(shí)例來(lái)拋出異常的。CreationPlicy<T>中的Create()和Destroy()兩函數是用來(lái)創(chuàng )建并摧毀具體對象的。 class A{}; typedef SingletonHolder<A, CreateUsingNew> SingleA;2、應用二 class A{}; class Derived : public A {}; template<class T> struct MyCreator : public CreateUsingNew<T> { static T* Create() { return new Derived; } static void Destroy(T* pInstance) { delete pInstance; } } typedef SingletonHolder<A,MyCreator> SingleA; 通過(guò)上面示例可以看出, SingletonHolder采用基于plicy設計實(shí)現,它將Singleton對象分解為數個(gè)policies,模板參數類(lèi)中CreationPolicy和LifetimePolicy相當于二個(gè)policies封裝體。利用它們可以協(xié)助制作出使用者自定義的Singleton對象,同時(shí)還預留了調整和擴展的空間。由此而得,泛型組件(generic components),是一種可復用的設計模板,結合了模板和模式,是C++中創(chuàng )造可擴充設計的新方法,提供了從設計到代碼的簡(jiǎn)易過(guò)渡,幫助我們編寫(xiě)清晰、靈活、高度可復用的代碼。 

地址:陜西省西安市勞動(dòng)路90號院(臺板廠(chǎng)家屬院)六單元郵編:710082EMAIL:jingzhou_xu@163.net未來(lái)工作室(Future Studio)
聯(lián)系客服