博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
6.4-数据结构&算法-模板/函数模板/类模板/特化
阅读量:7067 次
发布时间:2019-06-28

本文共 14839 字,大约阅读时间需要 49 分钟。

一、为什么要有模板?
将类型参数化,可以实现算法与类型的分离,编写针对类型更加抽象的函数或者类。
 
二、函数模板
通用定义:
template<typename 类型形参1, ...>
返回类型 函数模板名 (形参表) { ... }
特化定义:
template<>
返回类型 函数模板名<类型实参1, ...> (形参表) { ... }
 
三、类模板
通用定义:
template<typename 类型形参1, ...>
class 类模板名 { ... };
全类特化:
template<>
class 类模板名<类型实参1, ...> { ... };
成员特化:
template<>
返回类型 类模板名<类型实参1, ...>
::成员函数名 (形参表) { ... }
 
四、局部特化
 
五、非类型参数和缺省参数
1.非类型参数的实参仅限于常量或者常量表达式。
2.无论类型参数还是非类型参数都可以带有缺省值,而且和函数的缺省参数一样,模板的缺省参数也必须靠右。
 
六、有关模板的其它问题
1.从模板继承
2.向模板派生
3.模板中模板成员
1)模板型成员变量
2)模板型成员函数
3)模板型成员类型
4.模板型模板实参
 
七、容器和迭代器

arg.cpp
#include 
using namespace std;template
class A {public: A (const T& t) : m_t (t) {} T m_t;};template
class Y>class B {public: B (const X& i, const Z& s) : m_i (i), m_s (s) {} Y
m_i; Y
m_s;};int main (void) { B
b (100, "hello"); cout << b.m_i.m_t << ' ' << b.m_s.m_t << endl; return 0;}

 

array.cpp

#include 
using namespace std;template
class Array {public: T& operator[] (size_t i) { return m_array[i]; } const T& operator[] (size_t i) const { return const_cast
(*this) [i]; } size_t size (void) const { return S; } friend ostream& operator<< (ostream& os, const Array& arr) { for (size_t i = 0; i < arr.size (); ++i) os << '(' << arr.m_array[i] << ')'; return os; }private: T m_array[S];};int main (void) { const /*volatile*/ int x = 3, y = 7; Array
arr; for (size_t i = 0; i < arr.size (); ++i) arr[i] = i; cout << arr << endl; Array
, 3> m; for (size_t i = 0; i < m.size (); ++i) for (size_t j = 0; j < m[i].size (); ++j) m[i][j] = i * m[i].size () + j; cout << m << endl; Array
a2; Array<> a3; return 0;}

 

cmp.cpp

#include 
#include
using namespace std;// 通用模板template
class Comparator {public: Comparator (T x, T y) : m_x (x), m_y (y) {} T min (void) const { return m_x < m_y ? m_x : m_y; } T max (void) const { return m_x > m_y ? m_x : m_y; }private: T m_x; T m_y;};/*// 针对char*的全模板特化template<>class Comparator
{public: Comparator (char* x, char* y) : m_x (x), m_y (y) {} char* min (void) const { return strcmp (m_x, m_y) < 0 ? m_x : m_y; } char* max (void) const { return strcmp (m_x, m_y) > 0 ? m_x : m_y; }private: char* m_x; char* m_y;};*/// 针对char*的成员函数特化template<>char* Comparator
::min (void) const { return strcmp (m_x, m_y) < 0 ? m_x : m_y;}template<>char* Comparator
::max (void) const { return strcmp (m_x, m_y) > 0 ? m_x : m_y;}int main (void) { cout << "输入两个整数:" << flush; int nx, ny; cin >> nx >> ny; Comparator
cn (nx, ny); cout << "最小值:" << cn.min () << endl; cout << "最大值:" << cn.max () << endl; cout << "输入两个字符串:" << flush; string sx, sy; cin >> sx >> sy; Comparator
cs (sx, sy); cout << "最小值:" << cs.min () << endl; cout << "最大值:" << cs.max () << endl; cout << "输入两个字符串:" << flush; char cx[256], cy[256]; cin >> cx >> cy; Comparator
cc (cx, cy); cout << "最小值:" << cc.min () << endl; cout << "最大值:" << cc.max () << endl; return 0;}

 

inher.cpp

#include 
using namespace std;template
class A {public: A (const T& t) : m_t (t) {} T m_t;};template
class B : public A
{public: B (const T& t, const Y& y) : A
(t), m_y (y) {} Y m_y;};int main (void) { B
b (100, "hello"); cout << b.m_t << ' ' << b.m_y << endl; return 0;}

 

inter.cpp

#include 
using namespace std;template
class A {public: class B {};};template
void foo (void) { typename A
::B b;}int main (void) { foo
(); return 0;}

 

list.cpp

#include 
#include
#include
using namespace std;// 双向线性链表容器模板template
class List {public: // 构造、析构、拷贝构造、拷贝赋值 List (void) : m_head (NULL), m_tail (NULL) {} ~List (void) { clear (); } List (const List& that) : m_head (NULL), m_tail (NULL) { for (Node* node = that.m_head; node; node = node->m_next) push_back (node->m_data); } List& operator= (const List& that) { if (&that != this) { List list (that); swap (m_head, list.m_head); swap (m_tail, list.m_tail); } return *this; } // 获取首元素 T& front (void) { if (empty ()) throw underflow_error ("链表下溢!"); return m_head->m_data; } const T& front (void) const { return const_cast
(this)->front (); } // 向首部压入 void push_front (const T& data) { m_head = new Node (data, NULL, m_head); if (m_head->m_next) m_head->m_next->m_prev = m_head; else m_tail = m_head; } // 从首部弹出 void pop_front (void) { if (empty ()) throw underflow_error ("链表下溢!"); Node* next = m_head->m_next; delete m_head; m_head = next; if (m_head) m_head->m_prev = NULL; else m_tail = NULL; } // 获取尾元素 T& back (void) { if (empty ()) throw underflow_error ("链表下溢!"); return m_tail->m_data; } const T& back (void) const { return const_cast
(this)->back (); } // 向尾部压入 void push_back (const T& data) { m_tail = new Node (data, m_tail); if (m_tail->m_prev) m_tail->m_prev->m_next = m_tail; else m_head = m_tail; } // 从尾部弹出 void pop_back (void) { if (empty ()) throw underflow_error ("链表下溢!"); Node* prev = m_tail->m_prev; delete m_tail; m_tail = prev; if (m_tail) m_tail->m_next = NULL; else m_head = NULL; } // 删除所有匹配元素 void remove (const T& data) { for (Node* node = m_head, *next; node; node = next) { next = node->m_next; if (equal (node->m_data, data)) { if (node->m_prev) node->m_prev->m_next = node->m_next; else m_head = node->m_next; if (node->m_next) node->m_next->m_prev = node->m_prev; else m_tail = node->m_prev; delete node; } } } // 清空 void clear (void) { for (Node* next; m_head; m_head = next) { next = m_head->m_next; delete m_head; } m_tail = NULL; } // 判空 bool empty (void) const { return ! m_head && ! m_tail; } // 获取大小 size_t size (void) const { size_t count = 0; for (Node* node = m_head; node; node = node->m_next) ++count; return count; } // 插入输出流 friend ostream& operator<< (ostream& os, const List& list) { for (Node* node = list.m_head; node; node = node->m_next) os << *node; return os; }private: // 节点 class Node { public: Node (const T& data = 0, Node* prev = NULL, Node* next = NULL) : m_data (data), m_prev (prev), m_next (next) {} friend ostream& operator<< (ostream& os, const Node& node) { return os << '(' << node.m_data << ')'; } T m_data; // 数据 Node* m_prev; // 前指针 Node* m_next; // 后指针 }; bool equal (const T& a, const T& b) const { return a == b; } Node* m_head; // 头指针 Node* m_tail; // 尾指针public: // 正向迭代器 class Iterator { public: Iterator (Node* head = NULL, Node* tail = NULL, Node* node = NULL) : m_head (head), m_tail (tail), m_node (node) {} bool operator== (const Iterator& it) const { return m_node == it.m_node; } bool operator!= (const Iterator& it) const { return ! (*this == it); } Iterator& operator++ (void) { if (m_node) m_node = m_node->m_next; else m_node = m_head; return *this; } const Iterator operator++ (int) { Iterator old = *this; ++*this; return old; } Iterator& operator-- (void) { if (m_node) m_node = m_node->m_prev; else m_node = m_tail; return *this; } const Iterator operator-- (int) { Iterator old = *this; --*this; return old; } T& operator* (void) const { return m_node->m_data; } T* operator-> (void) const { return &**this; } private: Node* m_head; Node* m_tail; Node* m_node; friend class List; }; Iterator begin (void) { return Iterator (m_head, m_tail, m_head); } Iterator end (void) { return Iterator (m_head, m_tail); } Iterator insert (Iterator loc, const T& data) { if (loc == end ()) { push_back (data); return Iterator (m_head, m_tail,m_tail); } else { Node* node = new Node (data, loc.m_node->m_prev, loc.m_node); if (node->m_prev) node->m_prev->m_next = node; else m_head = node; node->m_next->m_prev = node; return Iterator (m_head, m_tail, node); } } Iterator erase (Iterator loc) { if (loc == end ()) throw invalid_argument ("无效迭代器!"); if (loc.m_node->m_prev) loc.m_node->m_prev->m_next = loc.m_node->m_next; else m_head = loc.m_node->m_next; if (loc.m_node->m_next) loc.m_node->m_next->m_prev = loc.m_node->m_prev; else m_tail = loc.m_node->m_prev; Node* next = loc.m_node->m_next; delete loc.m_node; return Iterator (m_head, m_tail, next); }};// 针对const char*的特化template<>bool List
::equal (const char* const& a, const char* const& b) const { return strcmp (a, b) == 0;}// 测试用例int main (void) { try { List
list1; list1.push_front (20); list1.push_front (10); list1.push_back (30); list1.push_back (40); cout << list1 << endl; cout << list1.front () << ' ' << list1.back () << endl; list1.pop_front (); list1.pop_back (); cout << list1 << endl; ++list1.front (); --list1.back (); cout << list1 << endl; list1.push_back (21); list1.push_back (25); list1.push_back (21); list1.push_back (21); cout << list1 << endl; list1.remove (21); cout << list1 << endl; List
list2 = list1; cout << list2 << endl; list2.back () = 100; cout << list2 << endl; cout << list1 << endl; list2 = list1; cout << list2 << endl; list2.front () = 100; cout << list2 << endl; cout << list1 << endl; cout << list1.size () << endl; list1.clear (); cout << list1 << endl; cout << boolalpha << list1.empty () << endl;// List
list3; List
list3; list3.push_back ("beijing"); list3.push_back ("tianjin"); list3.push_front ("tianjin"); list3.push_back ("shanghai"); list3.push_back ("beijing"); cout << list3 << endl; list3.remove (string ("beijing").c_str ()); cout << list3 << endl; for (List
::Iterator it = list3.begin (); it != list3.end (); ++it) cout << *it << ' '; cout << endl; List
::Iterator it = list3.begin (); it++; it = list3.insert (it, "chongqing"); cout << list3 << endl; list3.erase (it); cout << list3 << endl; } catch (exception& ex) { cout << ex.what () << endl; return -1; } return 0;}

 

max.cpp

#include 
using namespace std;int max_int (int x, int y) { return x > y ? x : y;}string max_str (string x, string y) { return x > y ? x : y;}int main (void) { cout << "输入两个整数:" << flush; int nx, ny; cin >> nx >> ny; cout << "最大值:" << max_int (nx, ny) << endl; cout << "输入两个字符串:" << flush; string sx, sy; cin >> sx >> sy; cout << "最大值:" << max_str (sx, sy) << endl; return 0;}

 

max2.cpp

#include 
#include
#include
using namespace std;// 函数模板/模板函数template
T Max (T x, T y) { cout << typeid (T).name () << endl; return x > y ? x : y;}// 模板特化template<>char* Max
(char* x, char* y) { return strcmp (x, y) > 0 ? x : y;}template
void foo (void) { T t; cout << typeid (t).name () << endl;}int main (void) { cout << "输入两个整数:" << flush; int nx, ny; cin >> nx >> ny; cout << "最大值:" << Max (nx, ny) << endl; cout << "输入两个字符串:" << flush; string sx, sy; cin >> sx >> sy; cout << "最大值:" << Max (sx, sy) << endl; cout << "输入两个字符串:" << flush; char cx[256], cy[256]; cin >> cx >> cy; cout << "最大值:" << Max (cx, cy) << endl; /* foo
(); foo
(); foo
(); */ return 0;}

 

memb1.cpp

#include 
using namespace std;template
class A {public: A (const T& t) : m_t (t) {} T m_t;};template
class B {public: B (const T& t, const Y& y) : m_a (t), m_y (y) {} A
m_a; Y m_y;};int main (void) { B
b (100, "hello"); cout << b.m_a.m_t << ' ' << b.m_y << endl; return 0;}

 

memb2.cpp

#include 
using namespace std;template
class A {public: A (const T& t) : m_t (t) {} /* template
void print (const Y& y) { cout << m_t << ' ' << y << endl; } */ template
void print (const Y& y); T m_t;};template
template
void A
::print (const Y& y) { cout << m_t << ' ' << y << endl;}int main (void) { A
a (100); a.print
("hello"); return 0;}

 

memb3.cpp

#include 
using namespace std;template
class A {public: A (const T& t, const Y& y) : m_t (t), m_b (y) {} /* template
class B { public: B (const X& x) : m_x (x) {} X m_x; }; */ template
class B; T m_t; B
m_b;};template
template
class A
::B {public: B (const X& x) : m_x (x) {} X m_x;};int main (void) { A
a (100, "hello"); cout << a.m_t << ' ' << a.m_b.m_x << endl; return 0;}

 

part.cpp

#include 
using namespace std;template
class A {public: A (void) { cout << "A
" << endl; }};template
class A
{public: A (void) { cout << "A
" << endl; }};template<>class A
{public: A (void) { cout << "A
" << endl; }};template
class B {public: B (void) { cout << "B
" << endl; }};template
class B
{public: B (void) { cout << "B
" << endl; }};template
class B
{public: B (void) { cout << "B
" << endl; }};template
class C {public: C (void) { cout << "C
" << endl; }};template
class C
{public: C (void) { cout << "C
" << endl; }};template
class C
{public: C (void) { cout << "C
" << endl; }};int main (void) { // 特化程度高的优先 A
a1; A
a2; A
a3; // 针对指针和数组的特化优先 B
b1; B
b2; B
b3; // 匹配度高的特化优先 C
c1; C
c2; C
c3; return 0;}

 

shape.cpp

#include 
using namespace std;template
class Shape : public BASE {public: void draw (void) const { BASE::draw (); }};class Rect {public: void draw (void) const { cout << "绘制矩形..." << endl; }};class Circle {public: void draw (void) const { cout << "绘制圆形..." << endl; }};int main (void) { Shape
shape1; shape1.draw (); Shape
shape2; shape2.draw (); return 0;}

 


 
 
 
 
 
 
 
 
 

转载于:https://www.cnblogs.com/xuxaut-558/p/10028385.html

你可能感兴趣的文章
CentOS自动挂载NTFS分区的U盘或者移动硬盘
查看>>
2018-2019-1 20165226 20165310 20165315 实验二 固件程序设计
查看>>
安装windows后grub的恢复
查看>>
android学习总结(20120721)
查看>>
安装rrdtool时候的报错configure: error: Please fix the library issues listed above and try again....
查看>>
创建一个10G可用空间的RAID5
查看>>
snmp安装
查看>>
elasticsearch常用操作命令
查看>>
设置sqlplus提示符
查看>>
存储类说明符
查看>>
MySQL 简易序列
查看>>
nginx keepalive
查看>>
Markdown 语法说明
查看>>
CentOS 7.0安装配置LAMP服务器(Apache+PHP+MariaDB)
查看>>
Django 跨表查询--神奇的双下划线和点
查看>>
h3cte D图 搭建
查看>>
Linux 文件基本属性
查看>>
【转】js获取当前指定的前几天的日期(如当前时间的前七天的日期)
查看>>
javascript中对象字面量的理解
查看>>
centos 普通用户获得sudo超级权限
查看>>