zoukankan      html  css  js  c++  java
  • 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,
    "
             << "P to process a PO,or Q to quit.
    ";
    
        while(cin >> ch && std::toupper(ch)!= 'Q')
        {
            while(cin.get()!='
    ')
                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
    ";
                }
                else
                {
                    st.push(po);
                }
                break;
            case 'P':
            case 'p':
                if(st.isempty())
                {
                    cout << "stack already empty
    ";
                }
                else
                {
                    st.pop(po);
                    cout << "PO # "<<po<<" popped
    ";
                }
                break;
            }
            cout <<"Please enter A to add a purchase order,
    "
                     << "P to process a PO,or Q to quit.
    ";
        }
    
        cout<< "Bye
    ";
        return 0;
    }
  • 相关阅读:
    fiddler——异常退出以及session排序
    fiddler——设置断点,修改http响应
    fiddler——保存抓到的包(导出和导入)
    fiddler——session的操作
    基本套接字:套接字地址
    Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析
    用“DB查询分析器”的对象浏览器来展现数据库的数据字典
    基本套接字:UDP 客户端/服务器端
    信息编码:基本整型
    基本套接字:UDP 套接字
  • 原文地址:https://www.cnblogs.com/activity-life/p/3632797.html
Copyright © 2011-2022 走看看