C++ 的语法相比较于 C 语言的语法有所改变,并且增加了面向对象的思想。在 C++ 的面向对象设计中,封装,继承和多态是三个比较重要的概念。除此之外还有一部分很重要的内容,就是 STL 了。而 STL 的实现就是依托于模板实现的。
STL 实现最初是为了泛型编程(Generic Programming),泛型编程是为了能够使程序能够适应于多种数据类型。而泛型编程也需要依托于模板。
从上边的简单说明中也可以看出,借助模板能够实现泛型编程,泛型编程的一个作品就是 STL。而泛型编程是为了程序能够应用于多种数据类型,因此模板就实现了这部分功能,利用参数化数据类型使程序能够适应于多种数据类型。
函数模板
格式
templete<typename/class T>
datatype func(argu)
{
statement;
}
实例
#include <iostream>
using namespace std;
template<typename T>
T func(T x)
{
return x;
}
int main()
{
char x = 'x';
int y = 10;
double z = 1.1;
cout<<func(x)<<" "<<func(y)<<" "<<func(z)<<endl;
return 0;
}
结果为:
x 10 1.1
上边的程序虽然简单到没有什么实际意义,但结果表明,使用函数模板可以避免频繁地修改函数形参和返回值,如果函数体内部使用到 T,还可以避免修改对应的数据类型。
- 函数模板调用的过程为先将函数模板化实例化为函数,再发生函数调用
- 函数模板也不同于重载,重载要求函数名和返回值相同,而参数形参个数和类型以及函数体可以不同,但函数模板只能用于函数形参个数相同而类型不同,返回值不同而函数体相同的场合
类模板
类模板定义
template<typename T>
class classname
{
statement;
}
类内定义成员函数
template<typename T>
class classname
{
datatype func(argument)
{
statement;
}
}
类外定义函数
template<typename T>
datatype classname<T>::func(argument)
{
statement;
}
实例
// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
using std::cout;
using std::endl;
template <typename T>
class MYSTACK
{
public:
MYSTACK(int n):size(n),top(0){ header = new T[n]; }
bool isempty();
bool isfull();
void traval();
void push(T x);
T pop();
void destory();
private:
T *header;
int size;
int top;
};
template <typename T>
bool MYSTACK<T>::isempty()
{
return top == 0;
}
template <typename T>
bool MYSTACK<T>::isfull()
{
return top == size;
}
template <typename T>
void MYSTACK<T>::traval()
{
for(int i = 0;i < top;i++)
cout<<*(header+i)<<endl;
}
template <typename T>
void MYSTACK<T>::push(T x)
{
*(header+top) = x;
top++;
}
template <typename T>
T MYSTACK<T>::pop()
{
T tmp = *(header+top-1);
top--;
return tmp;
}
template <typename T>
void MYSTACK<T>::destory()
{
delete []header;
}
#endif // MYCLASS_H
// main.cpp
#include <iostream>
#include "myclass.h"
using namespace std;
int main()
{
MYSTACK<int> st(10);
cout<<st.isempty()<<endl;
for(int i = 0;i < 10;i++)
st.push(i);
st.traval();
cout<<st.isfull()<<endl;
for(int i = 0;i < 10;i++)
cout<<st.pop()<<endl;
st.destory();
MYSTACK<char> sd(10);
for(char i = 'a';i < 'k';i++)
sd.push(i);
sd.traval();
for(int i = 0;i < 10;i++)
cout<<sd.pop()<<endl;
sd.destory();
return 0;
}
结果为:
1
0
1
2
3
4
5
6
7
8
9
1
9
8
7
6
5
4
3
2
1
0
a
b
c
d
e
f
g
h
i
j
j
i
h
g
f
e
d
c
b
a
上边的程序中,我们想把模板类的声明和定义分开,但是在编译时却出现了:
error: undefined reference to `MYSTACK<int>::isempty()'
这意味着模板类的声明和定义需要放置在同一文件中,模板类文件后缀名为.hpp。