博客园  :: 首页  :: 新随笔  :: 管理

c++模板

Posted on 2020-01-04 19:28  wsg_blog  阅读(490)  评论(0编辑  收藏  举报

Index C++

c++模板

为什么要有模板(templates):当我们需要一个列表(list),列表中元素可能都为X类型也可能都为Y类型,怎么来实现呢?

  1. 定义基类?可以实现,很多情况下可能不够简明的表达设计思想
  2. 克隆代码(写一段X关于list的定义,再写一段Y关于list的定义)但是后期无法统一对其管理
  3. 做一个void*类型的list,缺点是类型不安全

比较好的解决方案就是Templates

  • 函数模板:是一种模板,用来做出函数,比如sort排序函数、swap交换函数等等
  • 类模板:也是一种模板,用来做出类,比如list、map等这些类

函数模板

swap函数 ====> swap函数模板

//swap函数
void swap(int& x, int& y)
{
    int temp = x;
    x = y;
    y = temp;
}
//swap函数模板
template <class T>
void swap(T& x, T& y)
{
    T temp = x;
    x = y;
    y = temp;
}

上边的T可以是int、float这种已有的类型,也可以是用户自己定义的类型。

int i=3;
int j = 4;
swap(i, j);    //这里编译时,编译器会帮我们按照之前templates定义的规则制造一个swap(int,int)函数

float k = 4.5;
flaot m = 3.7;
swap(k, m);  //这里编译器会给我们再做出一个 swap(flaot,flaot)函数 与上边的swap(int,int)是函数重载的关系

注意1:

swap(int,int);  //ok
swap(double, double);  //ok
swap(int, double);  //error!  并不会把double转为int

注意2:

//函数模板的另一种写法
template <class T>
void foo(void) {/*...*/}
foo <int>();    //foo(int)
foo<float>();  //foo(float)

模板中使用用多个类型:

template <class K, class V>
class HashTable
{
    const Value& lookup(const K&) const;
    const install(const K&, const V&);
    ...
};

模板中使用参数:

template<class T, int bounds=100>  //注意这里的bounds变量,有缺省的值,也可以在后边定义类对象的时候赋值
class FixedVector
{
public:
    FixedVector();
    //...
    T& operator[] (int);
private:
    T element[bounds]; //fixed size array!
};

FixedVector<int, 50> v1;  //种出一个50个单元的int的FixedVector
FixedVector<int> v2;    //默认100个单元

类模板

template <class T>
class Vector
{
public:
    Vector(int);
    ~Vector();
    Vector(const Vector&);
    Vector& operator=(const Vector&);
    T& operator[] (int);
private:
    T* m_elements;
    int m_size;
};

//使用
Vector<int> v1(100);  //Vector中的T是int
Vector<Complex> v2(256);  //Complex 可以是float等类型

v1[20] = 10;
v2[20] = v1[20];  //ok if int->Complex 如果int能转换为Complex(向上造型)

T某个成员变量的类型,T做成员函数的返回类型

函数模板遇到继承会怎样?

某个类继承了某个模板种出来的类,什么叫“种”,就是在编译的时候,编译器根据我们定义的模板来给你生成了一段真实的类的代码

template <class A>
class Derived:public Vector<A> {...};  //Vector借用上一段代码