码迷,mamicode.com
首页 > 编程语言 > 详细

c++学习笔记啊——类模板(1)

时间:2015-06-13 06:18:17      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:

模板

  • 模板是泛型编程的基础,能够处理在编译时不知道类型的情况

(1)模板函数

  • 模板函数(function template)
  • 一个模板函数就是一个公式,可以用来生成针对特定类型的函数版本,如下compare模板的例子
1 template < typename T >
2 int compare(const T&v1,const T&v2)
3 {
4     //其实只要返回一个值,后面的就不会再执行了
5     if(v1v2) return 1;
6     return 0;
7 }

函数说明:

  1. 模板定义以关键字**template**开始
  2. 关键字之后的是模板参数列表,如果有多个参数,可以用逗号分开,且模板参数列表不能为空

总的来说:

compare函数声明了一个名为T的类型参数,在compare中我们用T来表示一种类型,而T的实际类型则是在编译时根据compare的使用情况来确定的。

(3)类模板

我们用栈类(stack)作为基础来建立模板

我们之前的一个stack的类声明如下

 1 typedef unsigned long Item;
 2 
 3 class stack
 4 
 5 {
 6 
 7 private:
 8     enum{MAX=10};
 9 
10     Item item[MAX];
11 
12     int top;
13 
14 public:
15 
16     //下面是一些栈类一些基本的方法
17 
18     //构造函数
19 
20     stack();
21 
22     //检验空栈,满栈
23 
24     bool isempty() const;
25 
26     bool isfull() const; 
27 
28     //入栈  
29 
30     bool push(const Item& item);
31 
32     //出栈
33 
34     bool pop(Item& item);
35 
36 };
  • 说明:语句typedef unsigned long Item;仅仅是为了编码的简单,他的意思是用Item来代替unsigned long

我们使用模板来编辑上述代码

首先,我们要告诉编辑器,我们这里定义一个模板

  • 语句template< typename Type >
  1. typename是变量名,标明Type是一个通用的变量说明符
  2. 当模板被调用时,Type将被具体的类型值(int或string取代)

其次,使用模板成员函数替换类方法

  • 模板声明打头
  • 修改限定符

具体代码片段

1 template < typename Type >
2 stack::stack()
3 {
4     top=0;
5 }

注意:

 

  1. 每一个函数实现上都要加上模板声明
  2. 不能将模板的成员函数放在独立的实现文件中,因为:模板不是函数,不能单独编译,模板必须与特定的模板实例化请求一起使用,最简单的就是放在一个头文件中

完整的头文件

 1 //typedef unsigned long Item;
 2 #ifndef STACK_H_
 3 #define STACK_H_
 4 template 
 5 //栈的操作准则:先进后出
 6 class stack
 7 {
 8 private:
 9     enum{MAX=10};
10     //一个数组,每个类型都是unsigned long,这里是因为简单所以加了
11     //typedef unsigned long Item;
12     Type items[MAX];
13     int top;
14 public:
15     //下面是一些栈类一些基本的方法
16     //构造函数
17     stack();
18     //检验空栈,满栈
19     bool isempty() const;
20     bool isfull() const;
21     //入栈
22     bool push(const Type& item);
23     //出栈
24     bool pop(Type& item);
25 };
26 
27 template 
28 stack::stack()
29 {
30     top=0;
31 }
32 
33 template 
34 bool stack::isempty()
35 {
36     //这是一个判断,千万别看错了
37     //两个==
38     return top==0;
39 }
40 
41 template 
42 bool stack::isfull()
43 {
44     return top==MAX;
45 }
46 
47 template 
48 bool stack::push(const Type&item)
49 {
50     if(top
51 bool stack::pop(Type&item)
52 {
53     if(top>0)
54     {
55         item = items[--top];
56         return true;
57     }
58     else
59         return false;
60 }
61 #endif

使用类模板
我们在头文件中包含了模板,但是,要生成模板类还必须请求实例化,也就是需要声明一个类型为模板类的对象

语法:

stack< int >kernels;
stack< string >colonels;

 

说明:

  • 编译器将按照stack< Type >模板生成两组独立类声明和类方法
  • 必须显示的提供所需类型
    这里与函数模板不同,编译器可以根据函数的参数确定生成那个版本的函数,

代码片段——栈程序测试

 1 #include< iostream>
 2 #include< string>
 3 //这个是干嘛的
 4 #include< cctype>
 5 #include"stack.h"
 6 using std::cin;
 7 using std::cout;
 8 
 9 int main()
10 {
11     //模板类的实例化
12     //创造一个模板类对象
13     Stack st;
14     char ch;
15     std::string po;
16     cout<<"please enter A to add a purchase order.\n"
17         <<"p to process a PO,or Q to quit.\n";
18     while(cin>>ch && toupper(ch)!=Q)
19     {
20         while(cin.get() !=\n)
21           continue;
22         if(!isalpha(ch))
23         {
24             cout<<\a;
25             continue;
26         }
27         switch(ch)
28         {
29         case A:
30         case a:  cout<<"enter a PO number to add: ";
31                   cin>>po;
32                   if(st.isfull())
33                       cout<<"stack already full\n";
34                   else
35                       st.push(po);
36                   break;
37         case P:
38         case p: if(st.isempty())
39                   {
40                       cout<<"stack already empty\n";
41                   }
42                   else
43                   {
44                       st.pop(po);
45                       cout<<"po# "<<<" popped\n";
46                       break;
47                   }
48         }
49         cout<<"please enter A to add a purchase order.\n"
50         <<"p to process a PO,or Q to quit.\n";
51     }
52     cout<<"bye\n";
53     return 0;
54 }

问题一:

while(cin.get() !=‘\n‘)
continue;

上述这两条语句的连用,是为了检查输入的完成,比如说,你输入了nihao此时,ch的值是n(获取的是单个字符)语句cin.get() !=‘\n‘会读取下一个字符,并对他进行判断,如果是换行符,跳出循环,如果不是,接着读取下一个字符,知道遇到换行符为止

问题二:

 1 template < class Type >
 2 bool Stack< Type >::push(const Type&item)
 3 {
 4     if(top< MAX)
 5     {
 6         items[top++]=item;
 7         return true;
 8     }
 9     else
10         return false;
11 }
12 
13 template < class  Type >
14 bool Stack::pop(Type&item)
15 {
16     if(top>0)
17     {
18         item = items[--top];
19         return true;
20     }
21     else
22         return false;
23 }

这两个是关于入栈出栈的函数实现,栈的特点是:先进后出,注意:入栈时时top++,也就是items[0],执行完items[top++]=item;,top自增一,items[top]也就指向栈的下一个内存区域,确保下次赋值不会覆盖已有内存,而在出栈是采用的是item = items[--top];先移动指针,再进行操作

问题三:
函数toupper()功能:转换为大写字符。

 

c++学习笔记啊——类模板(1)

标签:

原文地址:http://www.cnblogs.com/rupengkun/p/4572905.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!