第二章C++ STL技术基础
2.1泛型与模板
泛型编程:采用一种通用的"类型"实现代码的编写,使程序独立于特定的数据类型
(1)函数模板
求两者中的最大值的函数模板
template <class T>(或者template <typename T>)
T Max(T a,T b)
{
return (a>b)?a:b;
}
用法:Max<int>(3,2);(尖括号也可省略,系统会自动识别3,2为int类型)
其中的T是“类型”的参数,T可以是int,float,char等数据类型
多类型的函数模板
template <class T1,class T2>
void swap(T1 &a, T2 &b)
{
T1 t;
t = a;
a = (T2)b;
b = (T1)t;
}
用法1:swap<double,int>(3,4.5);
函数模板重载
template <class T1>
int sum(T1 a, T1 b)
{
return a+b;
}
int sum(T1 a, T1 b, T1 c)
{
return a+b+c;
}
用法:
int a=1,b=2;
sum(a,b);
sum(a,b,c);
函数模板重载与普通函数重载一样,函数名相同参数个数不同
(2)类模板
(2.1)类模板的定义方法
template <class T>
class 类名
{
类体
};
以堆栈的类模板举例
堆栈类模板的定义
const int n = 10; //定义堆栈大小
template <class T> //数据类型参数化
class Stack //定义类模板
{
T stk[n]; //顺序栈,T为元素类型
int top; //栈顶元素的位置,注意此处的int类型并未参数化
public:
Stack()
{top = -1;}
void push(T ob); //入栈函数,T为参数类型
T pop(); //出栈函数,T为返回值类型
};
入栈函数的类外实现
template <class T>
void Stack<T>::push(T ob)
{
if(top==n-1)
{
cout<<"Stack is full"<<endl;
return;
}
stk[++top] = ob;
}
出栈函数的类外实现
template <class T>
T Stack<T>::pop()
{
if(top<0)
{
cout<<"stack is empty"<<endl;
return(0);
}
return stk[top--];
}
类模板实例化
int main()
{
Stack<char> s1;
Stack<int> s2,*sp=&s2;
s1.push('a');
s1.push('b');
s1.push('c');
cout<<"pop s1:";
for(int i=0;i<3;i++)
cout<<s1.pop();
s2.push(1);
s2.push(2);
s2.push(3);
cout<<endl<<"pop s2:";
for(int i=0;i<3;i++)
cout<<sp->pop();
cout<<endl;
return 0;
}
(2.2)类模板的其他语法规则
全局类型与模板类型同名
typedef string type //此处的type是全局类型
template <class type>
class G
{
```
type n; //n的类型由类模板实例化过程中的实际类型决定,不是string类型,即局部优先原则
```
};
类型参数带缺省类型
template <class T1=char,class T2=int>
class A
{
T1 m1;
T2 m2;
......
};
T1的缺省值为char,T2的缺省值为int
注:
缺省值的设置须从右到左,而实例化时的赋值顺序是从左到右
template <class T1=int,class T2> class X //错误
template <class T1,class T2=int> class Y //正确
实例化
A<> a //T1=char,T2=int
A<double> b // T1=double,T2=int
A<int,bool> c //T1=int,T2=bool
类模板组合
定义:在类模板的定义中,内嵌自身或其他类模板的对象的定义方式
template <class U>
class A
{
A<U> *p; //<U>也可省略
};
template <class U>
class B
{
A<U> &a,*b; //<U>不可省略
};