C++ 模板

模板的作用

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。
模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。

  1. 模板分为函数模板和类模板,函数模版是用来生成函数的实例,类模版是用来生成类的实例。
  2. 一个模版就是一个类或函数的蓝图或者说是公式。当我们调用template时,编译器会使用实参的类型来确定绑定到模版参数T上的类型,之后编译器利用推断出的模版参数来实例化一个特定版本的函数,这个过程被称之为实例化。
  3. 编译器遇到一个模版的定义时,并不会产生代码,只有当我们实例化出模版的一个特定版本的时候,编译器才会产生代码。编译器遇到一个模版的定义时,并不会产生代码,只有当我们实例化出模版的一个特定版本的时候,编译器才会产生代码。
  4. 需要保证传递给模版的实参支持模版的所有操作(例如传入的是addr类型,则在类模板中操作"<“运算符时,addr类型需要实现重载这个运算符),以及这些操作在模版中正确工作。需要保证传递给模版的实参支持模版的所有操作(例如传入的是addr类型,则在类模板中操作”<"运算符时,addr类型需要实现重载这个运算符),以及这些操作在模版中正确工作。

函数模板:一个函数模版就是一个公式,可用来生成指定类型的函数版本,例如需要编写一个函数比较两个值,如果没有模板,则需要为各种类型(例如int,double,string等)各自编写一个比较函数。
类模板:类模板是用来生成类的模型,和函数模板不同的是,编译器不能为类模板推断模板参数类型,必须提供实参列表。这个是显然的,因为函数是直接调用,传入的参数可以推断出类型,但是类需要定义,如果不指定类型,则是不行的。

函数模板

类模板

参考这篇文章

1. 基础的模板类

类模板,可以定义相同的操作,拥有不同数据类型的成员属性。
通常使用template来声明。告诉编译器,碰到T不要报错,表示一种泛型。
如下,声明一个普通的类模板:

template <class T>
class Stack { 
  private: 
    vector<T> elems;          // 元素 
  public: 
    void push(T const&);      // 入栈
    void pop();               // 出栈
    T top() const;            // 返回栈顶元素
    bool empty() const{       // 如果为空则返回真。
        return elems.empty(); 
    } 
}; 
 // 如果在类外定义成员函数,若此成员函数中有模板参数存在,
 // 则除了需要和一般类的类外定义成员函数一样的定义外,
 // 还需要在函数外进行模板声明
template <class T>
void Stack<T>::push (T const& elem) { } 
 
template <class T>
void Stack<T>::pop () { } 
 
template <class T>
T Stack<T>::top () const {  } 

int main()
{
    //对象的定义,必须声明模板类型,因为要分配内容
    Stack<int> a;  
    Stack<int> b;
    return 0;
}

2 模板类的继承

在模板类的继承中,需要注意以下几点:

  • 如果父类自定义了构造函数,记得子类要使用构造函数列表来初始化
  • 继承的时候,如果子类不是模板类,则必须指明当前的父类的类型,因为要分配内存空间
  • 继承的时候,如果子类是模板类,要么指定父类的类型,要么用子类的泛型来指定父类
template <typename T>
class Parent{
public:
    Parent(T p)
    {
        this->p = p;
    }
    
private:
    T p;
};
//如果子类不是模板类,需要指明父类的具体类型
class ChildOne:public Parent<int>{
public:
    ChildOne(int a,int b):Parent(b)
    {
        this->cone = a;
    }
private:
    int cone;
};
//如果子类是模板类,可以用子类的泛型来表示父类
template <typename T>
class ChildTwo:public Parent<T>{    
public:
    ChildTwo(T a, T b):Parent<T>(b)
    {
        this->ctwo = a;
    }    
private:
    T ctwo;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值