類和模板小結
類和模板小結
標籤 :資料結構學習筆記
類
-
使用struct和class寫類的區別:
使用struct關鍵字,預設的訪問許可權是public,而使用class的預設訪問許可權是private,兩者唯一的區別就是預設的訪問許可權的不同 -
private和protect:
private成員變數或函式在類的外部是不可訪問的,甚至是不可檢視的。只有類和友元函式
可以訪問私有成員。
protect變數或函式與私有成員十分相似,但有一點不同,保護成員在派生類(即子類)
中是可訪問的。
eg:class SmallBox:Box // SmallBox 是Box的派生類 - 建構函式在定義變數的時候(早於手動為變數賦初值的過程)即會被呼叫
-
類的友元函式是定義在類外部,但有權訪問類的private成員和protected成員。
儘管友元函式的原型有在類的定義中出現過,但是友元函式並不是成員函式。
友元可以是一個函式,該函式被稱為友元函式;友元也可以是一個類,該類被稱為友元類,在這種情況下,整個類及其所有成員都是友元。
如果要宣告函式為一個類的友元,需要在類定義中該函式原型前使用關鍵字 friend,如下所示:
宣告類 ClassTwo 的所有成員函式作為類 ClassOne 的友元,需要在類 ClassOne 的定義中放置如下宣告:friend class ClassTwo; -
在 C++ 中,每一個物件都能通過 this 指標來訪問自己的地址。在成員函式內部,它可以用來指向呼叫物件。
友元函式沒有 this 指標,因為友元不是類的成員。只有成員函式才有 this 指標。
模板(其實挺簡單的,不要被嚇到了)
函式模板
-
模板就是把函式定義為對任意資料型別都通用的函式,也叫泛型函式,呼叫時候根據提供的實參替換成特定的資料型別
eg:交換模板:
template <typename T>//關鍵字typename或class,定義資料型別為 T(int,double.....) void swap(T &a,T &b){ T tmp; tmp=a; a=b; b=tap; }
-
<>裡面為模板引數,分為型別模板引數
(template <typename T>)
和非型別模板引數(template<int n,int m>int compare(const char (&p1)[n],const char (&p2)[m]{函式體})
類模板
正如我們定義函式模板一樣,我們也可以定義類模板。泛型類宣告的一般形式如下所示:
template <class typename> class class-name { . . . }
typename定義型別。您可以使用一個逗號分隔的列表來定義多個泛型資料型別。
下面的例項定義了類 Stack<>,並實現了泛型方法來對元素進行入棧出棧操作:
#include <iostream> #include <vector> #include <cstdlib> #include <string> #include <stdexcept> using namespace std; template <class T> class Stack { private: vector<T> elems;// 元素 public: void push(T const&);// 入棧 void pop();// 出棧 T top() const;// 返回棧頂元素 bool empty() const{// 如果為空則返回真。 return elems.empty(); } }; template <class T> void Stack<T>::push (T const& elem) { // 追加傳入元素的副本 elems.push_back(elem); } template <class T> void Stack<T>::pop () { if (elems.empty()) { throw out_of_range("Stack<>::pop(): empty stack"); } // 刪除最後一個元素 elems.pop_back(); } template <class T> T Stack<T>::top () const { if (elems.empty()) { throw out_of_range("Stack<>::top(): empty stack"); } // 返回最後一個元素的副本 return elems.back(); } int main() { try { Stack<int>intStack;// int 型別的棧 Stack<string> stringStack;// string 型別的棧 // 操作 int 型別的棧 intStack.push(7); cout << intStack.top() <<endl; // 操作 string 型別的棧 stringStack.push("hello"); cout << stringStack.top() << std::endl; stringStack.pop(); stringStack.pop(); } catch (exception const& ex) { cerr << "Exception: " << ex.what() <<endl; return -1; } }
當上面的程式碼被編譯和執行時,它會產生下列結果:
7 hello Exception: Stack<>::pop(): empty stack