C++模板類[初步]

/*
 * stacktp.h
 *
 *  Created on: 2014年3月29日
 *      Author: 
 */
/**
 *    - 模板類的概念,與使用
 *        -# export template <class Type>
 *          <li> export 關鍵字表示導出這個模板類,使用此關鍵,使得能夠把
 *                 模板類的聲明放在頭文件中,而定義分開放在.cpp的文件中.
 *               有些編譯器沒有實現此關鍵字,所以必須把定義與聲明放在頭文件中
 *               不然編譯通不過
 *          </li>
 *          <li> template 關鍵字,表示聲明一個模板類</li>
 *          <li> <class Type> 表示要傳給這個模板類的參數
 *               class 這個關鍵字,表示參數的類型,這個關鍵字能夠用 Typename這個關鍵字替代
 *               Type 是參數的名字,也即變量名.C++習慣上用T表示
 *               關鍵理解:
 *                咱們要抓住:"模板"和"模板類"這兩個概念. 有句話叫:依葫蘆畫飄瓢。意思是說按照葫蘆的樣子畫瓢。
 *                用來類比的話就是說"模板"對應那個葫蘆,"類"對應那個瓢.同理,模板類的意思是告訴C++編譯器按
 *               照模板類來生成具體的類代碼。具體的類代碼的函數和算法是相同的,不一樣的部分就是 <class Type>
 *              指定的那部分,這部分是編譯器要按照咱們使用時指定的參數的不一樣,編譯時生成相應的代碼,再也不須要
 *              手寫和粘貼複製了.編譯器在幫程序員偷懶(從小的角度來看),提升一個層次來看,就叫通用編程.就是說
 *        編寫一段通用的代碼,傳入什麼的樣的參數,就生成相應用的具體代碼。從數學的角度來講,就是寫了一個
 *        公式或者說函數;不一樣的取值範圍和具體的量化,產生不一樣的結果。好比y=a+k(x),假如a,k是常量,根據x
 *        的取值不一樣,相應的y也不一樣。從這裏來理解,用模板寫一些算法性質的代碼,那簡值太妙了,特別是一些經常使用的
 *        算法,能夠少死不少腦細胞.
 *          </li>
 *   -此類來自於C++ primer Plus(第五版)第14章
 *          -# 模擬實現一個堆棧,棧空間最大爲10
 *
 *
 */
#ifndef STACKTP_H_
#define STACKTP_H_
// export template <class Type>
template <class Type>
class Stack
{
private:
    enum{MAX =10};
    Type items[MAX];
    int top;
public:
    Stack();
    bool isempty();
    bool isfull();
    bool push (const Type & item);
    bool pop (Type & item);
};


 /**
  *下面的書寫形式,要講一下
  *template <class Type> //這一部分參考頭文件的說明
  *    Stack<Type>::Stack()//這裏要說一下
  *    Stack :表示模板類的類名
  *    <Type>:表示傳給這個模板類的類型類參數,
  *           編譯器根據它的意思來生成具體的代碼.如終強調一點,咱們寫的是
  *           模板代碼。注意"模板"兩字。
  *    ::Stack():表示是Stack<Type>這個模板類的構造方法.
  *    回固一下知識。若是咱們本身寫了構造函數。那麼C++編譯器,就不會在編譯時偷偷的生成默認構造函數了.
  *
  */
 template <class Type>
 Stack<Type>::Stack()
 {
     top =0;
 }

 template <class Type>
 bool Stack<Type>::isempty()
 {
     return top == 0;
 }

 template <class Type>
 bool Stack<Type>::isfull()
 {
     return top == MAX;
 }

 template <class Type>
 bool Stack<Type>::push(const Type &item)
 {
     if(top < MAX){
         items[top++] = item;
         return true;
     }
     else{
         return false;
     }
 }

 template <class Type>
 bool Stack<Type>::pop(Type & item)
 {
     if(top>0){
         item = items[--top];
         return true;
     }
     else{
         return false;
     }
 }

#endif /* STACKTP_H_ */
//============================================================================
// Name        : TemplateClass_1.cpp
// Author      : 
// Version     :
// Copyright   : Free
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;
#include "stacktp.h"

int main() {

    /**
     *    注意:[1]
     *    咱們傳了std::string這個類型給Stack模板類
     *    編譯器是如何知道Stack是個模板類呢,或者說咱們是如何確
     *    Stack是個模板類呢,而不是普通的類呢。注意"<>"這對尖括號
     *    它表示類Stack還要接受一個類型參數,因此咱們從這裏肯定的。
     *    編譯器也是經過<>來識別的。咱們其實能夠想象普通的非模板類,
     *    也有一對尖括號的,也接受了一個參數,只是這個參數在非模板類
     *    的定義裏面沒有用到,沒有使用這個參數,因此傳了也沒有用。
     *    這樣一想,能夠在概念上把非模板類和模板類統一認爲是模板類了。
     *    非模板類,是模板類的一個子集。
     *    注意:[2]
     *    Stack<std::string> st; //這裏雖然只寫了一句,但實際編譯後不僅是這句話,
     *    而是以下一段代碼:
     *  Stack<std::string> st = new Stack();
     *  可是這裏有個前提條件,咱們必須有一個默認構造函數,不然C++編譯器不知道,怎樣
     *  初始化這個st對象。而報語法錯誤.
     *  而在Java中,定義的對象都是引用。必需要new纔會初始化.
     *  所以咱們要記住一點,在面向對象的世界裏,全部的對象都要有初值,要有一個肯定的狀態.
     *  若是容許,對象有不肯定的狀態,那麼就沒有那麼了...
     *
     */

    Stack<std::string> st;
    char ch;
    std::string po;
    cout <<"Please enter A to add a purchase order,\n"
         << "P to process a PO,or Q to quit.\n";

    while(cin >> ch && std::toupper(ch)!= 'Q')
    {
        while(cin.get()!='\n')
            continue;
        if(!std::isalpha(ch))
        {
            cout<< '\a';
            continue;
        }
        switch(ch)
        {
        case 'A':
        case 'a':
            cout <<"Please Enter a PO number to add:";
            cin>>po;
            if(st.isfull())
            {
                cout << "stack already full\n";
            }
            else
            {
                st.push(po);
            }
            break;
        case 'P':
        case 'p':
            if(st.isempty())
            {
                cout << "stack already empty\n";
            }
            else
            {
                st.pop(po);
                cout << "PO # "<<po<<" popped\n";
            }
            break;
        }
        cout <<"Please enter A to add a purchase order,\n"
                 << "P to process a PO,or Q to quit.\n";
    }

    cout<< "Bye\n";
    return 0;
}
相關文章
相關標籤/搜索