Chinaunix首页 | 论坛 | 博客
  • 博客访问: 48566
  • 博文数量: 14
  • 博客积分: 297
  • 博客等级: 二等列兵
  • 技术积分: 547
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-08 21:05
个人简介

努力做自己不喜欢的事情!

文章分类
文章存档

2013年(4)

2012年(10)

我的朋友

分类: C/C++

2012-10-27 22:28:57

类模板
 
What's the Class Template?
定义:可以被一种或多种类型参数化的类
 
How Template?
  1. template <class T>
  2. class Stack
  3. {
  4.     ...
  5. };
在类模板内部,T可以像其他任何类型一样,用于声明成员变量和成员函数:

  1. template <typename T>
  2. class Stack {
  3.   private:
  4.     std::vector<T> elems; // elements

  5.   public:
  6.     Stack(); // constructor
  7.     void push(T const&); // push element
  8.     void pop(); // pop element
  9.     T top() const; // return top element
  10. };
类的类型是Stack,需要使用该类的类型时,你必须使用Stack:
  1. template <typename T>
  2. class Stack {
  3.     …
  4.     Stack (Stack<T> const&); // copy constructor
  5.     Stack<T>& operator= (Stack<T> const&); // assignment operator
  6.     …
  7. };
当使用类名而不是用类的类型时,就应该用Stack.
 
成员函数

必须指定成员函数是个模板函数:
  1. template <typename T>
  2. void Stack<T>::push (T const& elem)
  3. {
  4.     elems.push_back(elem); // append copy of passed elem
  5. }
类模板调用
只用被调用的成员函数才会被实例化,这样来节省空间和时间;另外一个原因是,用一些特殊且仅支持部分模板类成员的参数来实例化类模板:
  1. // basics/stack1test.cpp

  2. #include <iostream>
  3. #include <string>
  4. #include <cstdlib>
  5. #include "stack1.hpp"

  6. int main()
  7. {
  8.     try {
  9.         Stack<int> intStack; // stack of ints
  10.         Stack<std::string> stringStack; // stack of strings

  11.         // manipulate int stack
  12.         intStack.push(7);
  13.         std::cout << intStack.top() << std::endl;

  14.         // manipulate string stack
  15.         stringStack.push("hello");
  16.         std::cout << stringStack.top() << std::endl;
  17.         stringStack.pop();
  18.         stringStack.pop();
  19.     }
  20.     catch (std::exception const& ex) {
  21.         std::cerr << "Exception: " << ex.what() << std::endl;
  22.         return EXIT_FAILURE; // exit program with ERROR status
  23.     }
  24. }
类模板特化
 
可以用模板实参来特化模板类,和函数模板的重载类似,通过特化类模板,可以优化基于某种特定类型的实现或者克服某种特定类型在实例化类模板时所出现的问题。

特定类:
  1. template<>
  2. class Stack<std::string> {
  3.   …
  4. };
特定成员:
  1. void Stack<std::string>::push (std::string const& elem)
  2. {
  3.     elems.push_back(elem); // append copy of passed elem
  4. }
局部特化
  1. // partial specialization: both template parameters have same type
  2. template <typename T>
  3. class MyClass<T,T> {
  4.   …
  5. };

  6. // partial specialization: second type is int
  7. template <typename T>
  8. class MyClass<T,int> {
  9.   …
  10. };

  11. // partial specialization: both template parameters are pointer types
  12. template <typename T1, typename T2>
  13. class MyClass<T1*,T2*> {
  14.   …
  15. };
缺省模板参数

  1. // basics/stack3.hpp

  2. #include <vector>
  3. #include <stdexcept>

  4. template <typename T, typename CONT = std::vector<T> >
  5. class Stack {
  6.   private:
  7.     CONT elems; // elements

  8.   public:
  9.     void push(T const&); // push element
  10.     void pop(); // pop element
  11.     T top() const; // return top element
  12.     bool empty() const { // return whether the stack is empty
  13.         return elems.empty();
  14.     }
  15. };

  16. template <typename T, typename CONT>
  17. void Stack<T,CONT>::push (T const& elem)
  18. {
  19.     elems.push_back(elem); // append copy of passed elem
  20. }

  21. template <typename T, typename CONT>
  22. void Stack<T,CONT>::pop ()
  23. {
  24.     if (elems.empty()) {
  25.         throw std::out_of_range("Stack<>::pop(): empty stack");
  26.     }
  27.     elems.pop_back(); // remove last element
  28. }

  29. template <typename T, typename CONT>
  30. T Stack<T,CONT>::top () const
  31. {
  32.     if (elems.empty()) {
  33.         throw std::out_of_range("Stack<>::top(): empty stack");
  34.     }
  35.     return elems.back(); // return copy of last element
  36. }


阅读(1221) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~