C++ 模板

本文详细介绍了C++中的函数模板和类模板,包括它们的定义、语法和使用实例。通过具体的代码示例,展示了如何利用模板来简化代码,提高代码的复用性和泛型编程的能力。

函数模板

 

函数模板就是创建一个通用功能的函数,支持多总不同形参,简化重载函数的函数体设计

举个例子

int abs(int x)
{
   return x < 0? -x : x;
}

double abs(double x)
{
   return x < 0? -x : x;
}

这两个函数只是参数不同,其他都是一样的。

可以用函数模板来简化

template<typename T>
T abs(T x)
{
   return x < 0? -x : x;
}

在编译的时候,编译器会根据数据的类型和模板,自动生成一个该类型的函数

 

函数模板定义语法

语法形式:

template<函数模板参数表>

函数定义

模板参数表内容

类型参数:class(或typename)标识符

常量参数:类型说明符 标识符

模板参数:template<参数表>class 标识符

 

类模板

语法:

template<模板参数表>

class 类名

{类成员声明}

如果在类模板外定义其成员函数,则要采用以下形式

template<模板参数表>

返回类型名 类名<模板参数标识符列表>::函数名(参数表)

举个例子

#include<iostream>
#include<cstdlib>
using namespace std;
struct Student
{
int id;//学号
float gpa;//平均分
};

template<class T>
class Store
{
private:
T item;//存放任意类型的数据
bool haveValue;//标记item是否放入
public:
Store();
T &getElem();//提取数据函数
void putElem(const T &x)//存入数据函数
}

template<class T>
Store<T>::Store():haveValue(false){}
template<class T>
T&Store<T>::getElem()
{
.....
}
.....

int main()
{
Store<int> s1,s2;//使用类模板要在类名后加数据类型
Store<Student> s;

}

 

数组类模板

#ifndef VECTOR_H_INCLUDED
#define VECTOR_H_INCLUDED
template <class T>
class Vector
{
private:
    T *p;
    int sz;
public:
    Vector(int n);//构造函数
    Vector();
    ~Vector();//析构函数
    operator T*();//重载到T*类型的转换
    Vector(const Vector<T>& c);//拷贝构造函数
    Vector<T>& operator =(const Vector<T>& c);//重载=
    T& operator [](int n);//重载[]
    const T& operator [](int n)const;
    void resize(int n);//修改数组大小
    int getSize()const;//去数组大小
};
template <class T>
Vector<T>::Vector(int n):sz(n)
{
    if(n>=0)
    {
        p=new T[n];
    }
}
template <class T>
Vector<T>::~Vector()
{
    delete []p;
}
template <class T>
int Vector<T>::getSize()const
{
    return sz;
}
template<class T>
Vector<T>& Vector<T>::operator =(const Vector <T> &c)
{
    if(*this !=c)
    {
        if(c.sz!=sz)
        {
            sz=c.sz+1;
            delete p;
            p=new T[sz];
        }
        for(int i=0;i<sz;i++)
        {
            p[i]=c.p[i];
        }
    }
    return *this;
}
template<class T>
Vector<T>::Vector(const Vector<T> &c)
{
    sz=c.sz;
    delete p;
    p=new T[sz];
    for(int i=0;i<sz;i++)
    {
        p[i]=c.p[i];
    }
}
template<class T>
T& Vector<T>::operator [](int n)
{
    if(n>=0&&n<sz)
    {
        return p[n];
    }
}
template<class T>
const T&Vector<T>::operator [](int n)const
{
    if(n>=0&&n<sz)
    {
        return p[n];
    }
}
template<class T>
Vector<T>::operator T*()
{
    return p;
}
template<class T>
void Vector<T>::resize(int n)
{
    if(n<0)
        return ;
    if(n==sz)
        return ;
    T *newp=new T[n];
    int x=n>sz? sz:n;
    for(int i=0;i<x;i++)
        newp[i]=p[i];
    delete[] p;
    p=newp;
    sz=n;
}
#endif // VECTOR_H_INCLUDED

operator T*();//重载到T*类型的转换

没有返回类型,为什么需要重载指针呢

 

 

 

🔺C++模板类/模板函数的声明与定义应该放在头文件里,不要分开来写类中函数的声明与定义(比如在.H文件里声明某个成员函数,在.CPP文件里定义该成员函数),这样会导致连接错误。所应该将模板类/模板函数的定义与声明写在一个.h文件里。

比如

在类的头文件声明了一个函数 template<typename T> void fun(T a);

然后在另一个CPP 文件里 实现该函数

template<typename T> void fun(T a)

{

/*函数实现*/

}

 

这样就会报错,

解决的办法只能是在声明的时候直接实现函数,不要再把函数实现写在另一个CPP文件里,不过这样看起来结构很乱就是了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值