zoukankan      html  css  js  c++  java
  • 【C++ Primer 第16章】1. 定义模板 (一)

    类模板

      1 #include<iostream>
      2 #include<vector>
      3 #include<memory>
      4 using namespace std;
      5 
      6 template <typename T> class BlobPtr;
      7 template <typename T> class Blob;
      8 template <typename T> bool operator==(const Blob<T>&, const Blob<T>&);
      9 
     10 template<typename T> class Blob {
     11 friend class BlboPtr;
     12 friend bool operator==(const Blob<T>&, const Blob<T>&);
     13 public:
     14     typedef typename vector<T>::size_type size_type;
     15 
     16     Blob();
     17     Blob(initializer_list<T> il);
     18 
     19     size_type size() const     { return data->size(); }
     20     bool empty() const         { return data->empty(); }
     21     void push_back(const T&)   { data->push(t); }
     22     void push_back(T &&t)      { data->push_back(std::move(t)); }
     23 
     24     void pop_back();
     25     T& back();
     26     T& opearator[](size_type i);
     27 
     28 private:
     29     shared_ptr<vector<T>> data;
     30     void check(size_t i, const string &msg)
     31 };
     32 
     33 template <typename T>
     34 Blob<T>::Blob(): data(make_shared<vector<T>>()) {}
     35 
     36 template <typename T>
     37 Blob<T>::Blob(initializer_list<T> il): data(make_shared<vector<T>>(il)) {}
     38 
     39 temlate <typename T>
     40 void Blob<T>::check(size_type i, const string &msg) const
     41 {
     42     if (i >= data->size())
     43         throw out_of_range(msg);
     44 }
     45 template <typename T>
     46 void Blob<T>::pop_back()
     47 {
     48     check(0, "pop_back on empty Blob");
     49     data->pop_back();
     50 }
     51 
     52 template <typename T>
     53 T& Blob<T>::back()
     54 {
     55     check(0, "back om empty Blob");
     56     return data->back();
     57 }
     58 
     59 template <typename T>
     60 T& operator[](size_type i)
     61 {
     62     check(i,"subscript out of range");
     63     return (*data)[i];
     64 }
     65 
     66 /*--------------------------BlobPtr----------------------------------------------*/
     67 
     68 template <typename T> BlobPtr {
     69 public:
     70     BlobPtr(): curr(0) {}
     71     BlobPtr(Blob<T> &a, size_r sz = 0): wptr(a.data), curr(sz) {}
     72 
     73     T& opearator*() const;
     74 
     75     BlobPtr& operator++();      //后缀自增
     76     BlobPtr& opearator--(); 
     77     BlobPtr& opearator++(int);  //前缀自减
     78     BlobPtr& opearator--(int);
     79 
     80 private:
     81     size_t curr;
     82     weak_ptr<vector<T>> wptr;
     83     shared_ptr<vector<T>> check(size_t, const string&) const    
     84 };
     85 
     86 template <typename T>
     87 shared_ptr<vector<T>> BlobPtr<T>::check(size_t i, const string &msg) const
     88 {
     89     auto ret = wptr.lock();
     90     if (!ret)
     91         throw runtime_error("unbind BlobPtr");
     92     if (i >= ret->size())
     93         thow out_of_range(msg);
     94 }
     95 
     96 template <typename T>
     97 T& BlobPtr*() const
     98 {
     99     auto p = check(curr, "dereference past end");
    100     return (*p)[curr];
    101 }
    102 
    103 template <typename T>
    104 BlobPtr<T>& BlobPtr<T>::operator--()
    105 {
    106     --curr;
    107     check(curr, "decrement past bengin of BlobPtr");
    108     return *this;
    109 }
    110 
    111 template <typename T>
    112 BlobPtr<T>& BlobPtr<T>::opearator++()
    113 {
    114     check(curr, "unbound BlobPtr");
    115     ++curr;
    116     return *this;
    117 }
    118 
    119 template <typename T>
    120 BlobPtr<T>& BlobPtr<T>::operator++(int)  //后缀
    121 {
    122     BlobPtr ret = *this;
    123     ++*this;
    124     return ret;
    125 }
    126 
    127 template <typename T>
    128 BlobPtr<T>& BlobPtr<T>::operator--(int)
    129 {
    130     BlobPtr ret = *this;
    131     --*this;
    132     return ret;
    133 }
     1 template <typename T> class Pal;    // 前置申明,在将模板的一个特例声明为友元关系时要用到
     2 class C {                           // C是一个普通的非模板类
     3 friend class Pal<C>;                // 用C实例化的Pal是C的一个友元
     4 
     5 template <typename T> friend class Pal2;   // pal2的所有实例都是C的友元;这种情况无需前置申明
     6 };
     7 
     8 template <typename T> class C2 {   // C2本身是一个类模板
     9 friend class Pal<T>;               // C2的每个实例将相同实例化的Pal声明为友元
    10 template <typename X> friend class Pal2;  // Pal2的所有实例都是C2的每个实例的友元,不需要前置声明
    11 friend class Pal3;         // pal3是一个非模板类,它是C2所有实例的友元
    12                            // 不需要Pal3的前置声明    
    13 };

    控制实例化

    • 模板在使用时才会被实例化,相同的实例可能出现在对各对象文件中。

    • 当多个独立编译的源文件使用了相同的模板,并提供了相同的参数。那么每个文件都会有该模板的一个实例,在大系统中,这会增加额外开销。

    • 通过显示实例化,避免这种开销。

    extern template class Blob<string>             //声明
    template int compare(const int&, const int&)   //定义
  • 相关阅读:
    Fundamentals of Garbage Collection
    CLR的八大特性
    Navigation and Pathfinding
    Work-Stealing in .NET 4.0
    Graphics.Blit
    整数的可除性
    关于强度
    重心坐标空间
    性能测试中TPS和并发用户数
    LoadRunner 12.02 安装以及汉化教程
  • 原文地址:https://www.cnblogs.com/sunbines/p/9102726.html
Copyright © 2011-2022 走看看