1、stack內存能否借助標准模板容器管理呢?答案是肯定的,只需要多傳一個模板參數即可,而且模板參數還可以是缺省的,如下:
template> //此處末尾必須有空格,否則編譯出錯 class Stack { … private: CONT c_; };
如果沒有傳第二個參數,默認為deque 雙端隊列,當然我們也可以傳遞std::vector
2、示例:借助標准模板容器deque管理實現stack模板類
這裡的Stack是適配器,STL六大組件之一,代碼復用,不是通過繼承;通過現有的類實現模板類
Stack.h:
#ifndef _STACK_H_ #define _STACK_H_ #include#include using namespace std; template > //此處末尾必須有空格,否則編譯出錯 class Stack { public: Stack() : c_() { } ~Stack() { } void Push(const T &elem) { c_.push_back(elem); } void Pop() { c_.pop_back(); } T &Top() { return c_.back(); } const T &Top() const { return c_.back(); } bool Empty() const { return c_.empty(); } private: CONT c_; //借助標准模板容器 deque 管理實現stack }; #endif // _STACK_H_
main.cpp:
#include "Stack.h" #include#include using namespace std; int main(void) { //Stack s; //默認是deque實現 Stack > s; s.Push(1); s.Push(2); s.Push(3); while (!s.Empty()) { cout << s.Top() << endl; s.Pop(); } return 0; }
輸出為 3 2 1
即如果沒有傳遞第二個參數,堆棧和壓棧等操作直接調用deque
如程序中傳遞vector
二、成員模板
來看下面的例子:
#includeusing namespace std; template class MyClass { private: T value; public: void Assign(const MyClass &x) { value = x.value; } }; int main(void) { MyClass d; MyClass i; d.Assign(d); // OK d.Assign(i); // Error return 0; }
因為i 和 d 的類型不同,故會編譯出錯。可以用成員模板的方法解決:
#include為了支持 MyClassusing namespace std; template class MyClass { private: T value; public: MyClass() {} template MyClass(const MyClass &x) : value(x.GetValue()) { } template void Assign(const MyClass &x) { value = x.GetValue(); //當不同類型時,value私用,應通過成員函數調用 } T GetValue() const { return value; } }; int main(void) { MyClass d; MyClass i; d.Assign(d); // OK d.Assign(i); // OK MyClass d2(i); return 0; }
#include四、派生類與模板、面向對象與泛型編程using namespace std; template class MyClass { private: typename T::SubType* ptr_; }; class Test { public: typedef int SubType; //如果Test中沒有定義SubType類型,則編譯會失敗 }; int main(void) { MyClass mc; return 0; }
(一)、派生類與模板
1、為了運行的效率,類模板是相互獨立的,即獨立設計,沒有使用繼承的思想。對類模板的擴展是采用適配器(adapter)來完成的(如之前使用deque實現Stack)。通用性是模板庫的設計出發點之一,這是由泛型算法(algorithm)和函數對象(functor)等手段達到的。
2、派生的目標之一也是代碼的復用和程序的通用性,最典型的就是MFC,派生類的優點是可以由簡到繁,逐步深入,程序編制過程中可以充分利用前面的工作,一步步完成一個復雜的任務。
3、模板追求的是運行效率,而派生追求的是編程的效率。
(二)、面向對象與泛型編程
1、面向對象與泛型都依賴於某個形式的多態
(1)面向對象
(2)泛型動態多態(虛函數)
靜態多態(模板類,模板函數)
2、面向對象中的多態在運行時應用存在繼承關系。我們編寫使用這些類的代碼,忽略基類與派生類之間的類型差異。只要使用基類指針或者引用,基類類型對象、派生類類型對象就可以共享相同的代碼。
3、在泛型編程中,我們所編寫的類和函數能夠多態地用於編譯時不相關的類型。一個類或一個函數可以用來操縱多種類型的對象。
參考:
C++ primer 第四版
Effective C++ 3rd
C++編程規范