C++基础——类模板
2015-11-02 16:21
621 查看
类模板
类模板stack的实现
拷贝构造函数和赋值运算符
类模板的特化
局部特化
缺省模板实参
模板类
通过将
适配器
以某种既有容器作为底部结构,将其接口改变,使之符合“先进后出”的特性,形成一个
像这种
类的类型:Stack
进行类模板的特化时,每个成员函数都必须定义为普通函数,原来模板函数中的每个
在特化的版本中,我们也可将底层容器类型改变为
可以做如下的局部特化:
下述的代码将展示会优先使用哪些模板:
如果有多个局部特化同等程度地匹配某个声明,称这样的声明具有二义性。
为了解决第二种二义性,可提供一种指向相同类型指针的特化:
类模板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> { ... } // 局部特化:指定第二个模板参数为int template<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++实现JNI接口需要注意的事项
- myTemplate模板引擎
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性