C++ Primer Plus 学习笔记 第十四章 指针类型模板 模板多功能型 模板的具体化

程序示例

stcktp1.h

#ifndef STCKTP1_H_
#define STCKTP1_H_

template <class Type>
class Stack
{
  private:
    enum {SIZE = 10};
    int stacksize;
    Type * items;
    int top;
  public:
    explicit Stack(int ss = SIZE);
    Stack(const Stack & st);
    ~Stack() {delete [] items;}
    bool isempty() {return top == 0;}
    bool isfull() {return top == stacksize;}
    bool push(const Type & item);
    bool pop(Type & item);
    Stack & operator= (const Stack & st);
};

template <class Type>
Stack<Type>::Stack(int ss) : stacksize(ss), top(0)
{
  items = new Type [stacksize];
}

template <class Type>
Stack<Type>::Stack (const Stack & st)
{
  stacksize = st.stacksize;
  top = st.top;
  items = new Type [stacksize];
  for (int i = 0; i < top; i++)
    items[i] = st.items[i];
}

template<class Type>
bool Stack<Type>::push(const Type & item)
{
  if (top < stacksize)
  {
    items[top++] = item;
    return true;
  }
  else
    return false;
}

template<class Type>
bool Stack<Type>::pop(Type & item)
{
  if (top > 0)
  {
    item = items[--top];
    return true;
  }
  else
    return false;
}

template<class Type>
Stack<Type> & Stack<Type>::operator=(const Stack<Type> & st)
{
  if (this == &st)
    return *this;
  delete [] items;
  stacksize = st.stacksize;
  top = st.top;
  items = new Type [stacksize];
  for(int i = 0; i < top; i++)
    items[i] = st.items[i];
  return *this;
}

#endif

stkoptr1.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include "stcktp1.h"

const int Num = 10;
int main()
{
  std::srand(std::time(0));
  std::cout << "Please enter stack size: ";
  int stacksize;
  std::cin >> stacksize;
  Stack<const char *> st(stacksize);

  const char* in[Num] = {
    "1: Hank Gilgamesh", "2: Kiki Ishtar",
    "3: Betty Rocker", "4: Ian Flagranti",
    "7: Joy Almondo", "8: Xaverie Paprika",
    "9: Juan Morre", "10: Misha Mache"
  };
  const char* out[Num];

  int processed = 0;
  int nextin = 0;
  while (processed < Num)
  {
    if (st.isempty())
      st.push(in[nextin++]);
    else if(st.isfull())
      st.pop(out[processed++]);
    else if (std::rand() % 2 && nextin < Num)
      st.push(in[nextin++]);
    else
      st.pop(out[processed++]);
  }
  for (int i = 0; i < Num; i++)
    std::cout << out[i] << std::endl;

  std::cout << "Bye\n";
  return 0;
}

表达式参数类模板:

程序示例:

arraytp.h

#ifndef ARRAYTP_H_
#define ARRAYTP_H_

#include <iostream>
#include <cstdlib>

template<class T, int n>
class ArrayTP
{
  private:
    T ar[n];
  public:
    ArrayTP() {};
    explicit ArrayTP(const T & v);
    virtual T & operator[] (int i);
    virtual T operator[] (int i) const;
};

template<class T, int n>
ArrayTP<T, n>::ArrayTP(const T & v)
{
  for (int i = 0; i < n; i++)
    ar[i] = v;
}

template<class T, int n>
T & ArrayTP<T, n>::operator[](int i)
{
  if (i < 0 || i >= n)
  {
    std::cerr << "Error in array limits: " << i
        << " is out of range\n";
    std::exit(EXIT_FAILURE);
  }
  return ar[i];
}

template <class T, int n>
T ArrayTP<T, n>::operator[](int i) const
{
  if (i < 0 || i >= n)
  {
    std::cerr << "Error in array limits: " << i
        << " is out of range\n";
    std::exit(EXIT_FAILURE);
  }
  return ar[i];
}

#endif

twod.cpp

#include <iostream>
#include "arraytp.h"
int main()
{
  using std::cout;
  using std::endl;
  ArrayTP<int, 10> sums;
  ArrayTP<double, 10> aves;
  ArrayTP< ArrayTP<int, 5>, 10> twodee;

  int i, j;
  for (i = 0; i < 10; i++)
  {
    sums[i] = 0;
    for (j = 0; j < 5; j++)
    {
      twodee[i][j] = (i + 1) * (j + 1);
      sums[i] += twodee[i][j];
    }
    aves[i] = (double) sums[i] / 10;
  }
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 5; j++)
    {
      cout.width(2);
      cout << twodee[i][j] << ' ';
    }
    cout << ": sum = ";
    cout.width(3);
    cout << sums[i] << ", average = " << aves[i] << endl;
  }

  cout << "Done.\n";

  return 0;
}

运行结果:

多类型模板参数

就是模板参数是多个class

程序示例pairs.cpp

#include <iostream>
#include <string>

  using std::cout; 
  using std::cin;
  using std::endl;
  using std::string;

template <class T1, class T2>
class Pair
{
  private:
    T1 a;
    T2 b;
  public:
    T1 & first();
    T2 & second();
    T1 first() const { return a;}
    T2 second() const { return b;}
    Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) {}
    Pair() {}
};

template<class T1, class T2>
T1 & Pair<T1, T2>::first()
{
// 这个我是在测试调哪个first()
  cout << "1&";
  return a;
}
template<class T1, class T2>
T2 & Pair<T1, T2>::second()
{
  cout << "2&";
  return b;
}

int main()
{
  using std::cout;
  using std::cin;
  using std::endl;
  using std::string;
  Pair<string, int> ratings[4] =
  {
    Pair<string, int> ("The Purpled Duck", 5),
    Pair<string, int> ("Jaquie's Frisco Al Fresco", 4),
    Pair<string, int> ("Cafe Souffle", 5),
    Pair<string, int> ("Bertie's Eats", 3)
  };

  int joints = sizeof(ratings) / sizeof (Pair<string, int>);
  cout << "Rating:\t Eatery\n";
  for (int i = 0; i < joints; i++)
    cout << ratings[i].second() << ":\t "
         << ratings[i].first() << endl;

  cout << "Oops! Revised rating:\n";
  ratings[3].first() = "Bertie's Fab Eats";
  ratings[3].second() = 6;
  cout << ratings[3].second() << ":\t "
       << ratings[3].first() << endl;
  return 0;
}

类模板类型参数和非类型参数都可以指定默认值。 函数模板不支持类型参数带默认值。 但是非类型参数可以

以上都是模板隐式实例化

还有显示实例化

。。嗯。。。这有毛用?

然后是显示具体化

就是为特定具体类另外单独定义模板内容的

template <> class SortedArray<const char *> 例子中是 SortedArray<const char char*> 完全不知道为毛要多一个char

在使用char* 类的时候就会调用该显示具体化的模板

部分具体化

template<class T1> Pair<T1, int> {...} 

吧没有具体化的参数丢到前面的那个<>中去

C++调用模板的顺序:

具体化程度越高越优先调用。 有指针具体化的先调指针具体化版本。不然就用通用的转换。

完结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@凌晨三点半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值