C++基础——类模板
来源:互联网 发布:win10 休眠不关闭网络 编辑:程序博客网 时间:2024/06/08 08:35
- 类模板
- 类模板stack的实现
- 拷贝构造函数和赋值运算符
- 类模板的特化
- 局部特化
- 缺省模板实参
类模板
类模板stack的实现
有两个角度观察STL
中的stack
模板类
- 模板类
通过将stack
定义为模板类的形式实现stack
类实体对不同类型数据(模板参数指定)的存储支持。
template<typename T>class stack{...private: std::deque<T> elems;}
- 适配器
以某种既有容器作为底部结构,将其接口改变,使之符合“先进后出”的特性,形成一个stack
。STL deque
是双向开口的数据结构,以deque
作为底部结构并封闭其头端开口,便可实现一个stack
。STL
便以deque
作为缺省情况下的stack
的底部结构。(使用deque而不是vector来实现一个stack是有好处的,当删除元素时,deque会释放内存,当需要重新分配内存时,deque的元素不需要被移动)。
像这种狐假虎威
,完全以底部容器完成全部工作,而具有修改某物接口,形成另一种风貌性质者,称为adapter
(配接器)。STL的观点来看,stack往往不被归类为container
,而被归类为container adapter
,对底层容器的配接。
#include <deque>#include <stdexpt>template<typename T>class stack{public: void push(const T&); void pop(); const T& top() const; T& top(); bool empty() const { return elems.empty();}private: std::deque<T> elems;}template<typename T>void stack<T>::push(const T& elem){ elems.push_back(elem); // 末尾进}template<typename T>void stack<T>::pop(){ if (empty()) throw std::out_of_range("stack<>::pop(): empty stack"); elems.pop_back(); // 末尾出}template<typename T>const T& stack<T>::top() const{ if (empty()) throw std::out_of_range("stack<>::top(): empty stack"); return elems.back();}template<typename T>T& stack<T>::top(){ if (empty()) throw std::out_of_range("stack<>::top(): empty stack"); return elems.back();}
拷贝构造函数和赋值运算符
- 类名:Stack
- 类的类型:Stack
template<typname T>class Stack{public: Stack(const Stack<T>& rhs); Stack<T>& operator=(const Stack<T>& rhs);}
类模板的特化
可以使用模板实参来特化类模板。为了特化一个类模板,你必须在起始处声明一个template<>
(告诉编译器,这是一个特化版本),接下来声明用来特化的类模板的类型。如果你要特化一个类模板,你还要特化该类模板的所有成员函数。
template<>class Stack<std::string>{...}
进行类模板的特化时,每个成员函数都必须定义为普通函数,原来模板函数中的每个T
也被相应的特化的类型所取代:
void Stack<std::string>::push(const std::string& elem){ elems.push_back(elem);}
在特化的版本中,我们也可将底层容器类型改变为vector
,这说明,特化的实现可以和基本类模板(primary template)的实现完全不同。
局部特化
类模板可以被局部特化。在特定的环境下指定类模板的特定实现,并且要求某些模板参数仍然必须由用户来定义。
template<typename T1, typename T2>class MyClass{ ...}
可以做如下的局部特化:
// 局部特化:两个模板参数具有相同的类型 template<typename T>class MyClass<T, T>{ ...}// 局部特化:指定第二个模板参数为inttemplate<typename T>class MyClass<T, int>{ ...}// 局部特化,两个模板参数都是指针类型template<typename T1, typename T2>class MyClass<T1*, T2*>{ ...}
下述的代码将展示会优先使用哪些模板:
MyClass<int, float> mif; // MyClass<T1, T2>MyClass<float, float> mff; // MyClass<T, T>MyClass<float, int> mfi; // MyClass<T, int>MyClass<int*, float*> mp; // MyClass<T1*, T2*>
如果有多个局部特化同等程度地匹配某个声明,称这样的声明具有二义性。
MyClass<int, int> mii; // 错误:同等程度地匹配MyClass<T, T>, MyClass<T, int>MyClass<int*, int*> mpp; // 错误:同等程度地匹配MyClass<T, T>, MyClass<T1*, T2*>
为了解决第二种二义性,可提供一种指向相同类型指针的特化:
template<typename T>class MyClass<T*, T*>{...}
缺省模板实参
template<typename T, typename CONT = std::deque<T> >class Stack{public: void push(const T& elem);private: CONT elems;};template<typename T, typename CONT>void Stack<T, CONT>::push(const T& elem){ elems.push_back(elem);}
- <C/C++基础> 类模板
- 【基础C&C++】模板
- C++基础——类模板
- C++——模板
- C++——模板
- C++——tarjan模板
- C++——KMP模板
- 【c/c++】类模板
- 【C/C++】模板类
- 《C++语言基础》实践参考——复数模板类
- C++ 泛型编程基础——类模板
- 模板——函数模板、类模板
- 【c++】模板和模板类
- JAVA基础——模板设计方法
- C++基础——函数模板
- 类模板语法基础
- 模板——类模板
- 模板——类模板
- 第十周实践项目1—二叉树算法库
- 怎样理解阻塞非阻塞与同步异步的区别?
- CoreData
- 第十周 项目1 二叉树算法库
- OpenJudge13 Sticks
- C++基础——类模板
- 第9周 项目2 - 对称矩阵压缩存储的实现与应用
- UML——用例图
- 第4周项目3 -- 单链表应用(3)
- 第九周项目2-对称矩阵的压缩存储实现与应用
- 第十周 项目一 二叉树算法库
- 第九周 项目二(1)-压缩形式存储对称矩阵基本运算
- 第10周 项目1 - 二叉树算法库
- 开启系统的coredump文件设置