模板( template )、 STL(标准模板库)
在泛型编程技术里,仍需要编写自己的函数和类,但不必限定它们所使用的数据类型(int、double 或 myClass);
只需使用一个占位符(通常用字母T表示),然后用这个占位符来编写函数 。
模板的基本语法,只要把 template <type>
这行代码放在函数或类的前面就可以定义出一个模板;比如:template <class T>
,还可以使用 template <typename T>
。
模板用来告诉编译器:字母T将在接下来的函数里代表一种不确定的数据类型 。关键字 class 并不意味着今后只能用类来替换 T ,这只是一种约定俗成的写法。
函数模板
如果某个函数对所有数据类型都将进行同样的处理,就应该把它编写为一个模板。
如果某个函数对不同的数据类型将进行不同的处理(或者说执行不同的语句),就应该对它进行重载。
类模板
template <class T> //使用占位符T写出类的声明
class MyClass{ MyClass(); void swap(T &a, T &b); };
这样的话,类里的方法实际上将是一些函数模板,构造器的实现如下:
template <class T> MyClass<U>::MyClass(){} //不需要与在类声明里使用的那个保持一致
创建内联模板:在创建类模板时,避免类声明和类定义相分离的一个好办法是使用内联( inline )记号法 。
内联函数形式为:inline void funName() {}
在类里,内联方法的基本含义是在声明该方法的同时对它进行了定义。
如果类模板需要一种以上的类型,根据具体情况可以多使用几个占位符,比如template<class T, class U>
下面通过代码进一步了解模板:
#include <iostream>
#include <string>
template <class T>
class Stack{ /*因为在这个类里使用了动态内存,所以一定要给它增加一个副本构造器和一个赋值操作符,避免由于编译器以默认的“逐位复制”方式生成的副本导致的程序不能正确运行*/
//创建内联模板
public:
Stack(unsigned int size = 200)
{
this->size = size;
sp = 0;
data = new T[size];
}
~Stack()
{
delete[] data;
}
void push(T value)
{
data[sp++] = value;
}
T pop()
{
return data[--sp];
}
private:
unsigned int size;
unsigned int sp;
T *data ;
};
//下面这种代码结构是类声明和类定义相分离时的做法
/*template <class T> class Stack{ public: Stack(unsigned int size = 200); ~Stack(); void push(T value); //接受一个T类型的输入参数,把它压入栈中 T pop() ; //弹出一个T类型的值并返回 private: unsigned int size; unsigned int sp; T *data ; }; template <class T> Stack<T>::Stack(unsigned int size) { this->size = size; sp = 0; data = new T[size]; } template <class T> Stack<T>::~Stack() { delete[] data; } template <class T> void Stack<T>::push(T value) { data[sp++] = value; } template <class T> T Stack<T>::pop() { return data[--sp]; }*/
template <class T> //在使用模板时,最好把函数原型和实现代码放在一起
void swap(T &a, T &b) //输入参数是通过引用传递的
{
T temp;
temp = a;
a = b;
b = temp;
}
int main(int argc, char** argv) {
Stack<std::string> strStack(100); //创建一个字符串栈
strStack.push("xiuxiu");
strStack.push("Hello");
std::cout << "strStack.pop() returns " << strStack.pop() << std::endl;
std::cout << "strStack.pop() returns " << strStack.pop() << std::endl;
int i1 = 2;
int i2 = 7;
std::cout << "Before swap: i1 = " << i1 << ",i2 = " << i2 << std::endl;
swap(i1, i2); //交换两个整数的值,还可以使用swap<int>(i1,i2)
std::cout << "After swap: i1 = " << i1 << ",i2 = " << i2 << std::endl;
std::string s1 = "xiuxiu";
std::string s2 = "Come on";
std::cout << "Before swap: s1 = " << s1 << ",s2 = " << s2 << std::endl;
swap(s1, s2); //交换两个字符串的值
std::cout << "After swap: s1 = " << s1 << ",s2 = " << s2 << std::endl;
return 0;
}
运行结果为:
strStack.pop() returns Hello
strStack.pop() returns xiuxiu
Before swap: i1 = 2,i2 = 7
After swap: i1 = 7,i2 = 2
Before swap: s1 = xiuxiu,s2 = Come on
After swap: s1 = Come on,s2 = xiuxiu
C++入门(17):命名空间和模块化