• 【C++】模板简述(三):类模板


      上文简述了C++模板中的函数模板的格式、实例、形参、重载、特化及参数推演,本文主要介绍类模板.

    一、类模板格式

      类模板也是C++中模板的一种,其格式如下:

    template<class 形参名1, class 形参名2, ...class 形参名n>
    class 类名{ 
    ...
    };
    

      例如:我个人模拟实现的Vector的声明

    template<typename T>
    class Vector{
    public:
    	typedef T* Iterator;				//迭代器
    	typedef const T* ConstIterator;		//const类型迭代器
    public:
    	//类的成员函数
    	Vector();							//构造函数
    	Vector(const Vector&);				//拷贝构造
    	Vector& operator=(const Vector&);	//赋值运算符重载
    	~Vector();							//析构函数
    public:
    	//公共接口
    	void PushBack(const T &);			//尾插
    	void PopBack();						//尾删
    	Iterator Find(const T &);			//查找
    	void Insert(Iterator*);				//插入
    	void Erase(Iterator*);				//删除
    	void Size();						//获取有效元素个数
    	bool Empty();						//判断是否为空
    	void clear();						//清空
    public:
    	//迭代器接口
    	Iterator Begin();					//迭代器起始位置
    	Iterator End();						//迭代器结束位置
    private:
    	T *_start;
    	T *_finish;
    	T *_endOfStroage;
    };
    

    二、模板类的实例化

      只要有不同的类型,编译器就会实例化出一个对应的类,这点与函数模板非常相似.例如:

    Vector<int> v1;
    Vector<char> v2;
    

       当定义上述两个类型的Vector时,编译器会用int和char分别代替模板形参,重新编写Vector类,最后创建Vector<int>和Vector<char>类.

    三、非类型的模板参数

      对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数。例如:

    template<typename T,int SIZE=10>
    class Array{
    private:
    	T _arr[SIZE];
    };
    

       虽然非类型模板参数很好用,但是也有一些限制:

      注意:浮点数和类对象是不允许作为非类型模板参数的.

      ***函数模板不支持形参带默认值.

    四、类模板的特化

      模板的特话分为两种,全特化和偏特化.

      全特化是指,所有的模板参数都要进行特化.例如:

    template<typename T>
    class Vector{
    public:
        Vector();
        ~Vector();
    private:
        T *_start;
        T *_finish;
        T *_endOfStroage;
    };
    
    template<>
    class Vector<int>{
    public:
    	Vector();
    	~Vector();
    private:
    	int *_start;
    	int *_finish;
    	int *_endOfStroage;
    }
    //不需要模板参数
    Vector<int>::Vector(){
        //代码
    }
    

      从上述代码我们可以看出:特化后定义成员函数不需要加模板参数.

      偏特化,是指多个模板参数可以只特化一个或一部分.如:

    template<typename T1,typename T2>
    class Add{
    public:
    	Add();
    	~Add();
    private:
    	T1 _left;
    	T2 _right;
    };
    
    //只特化第一个参数
    template<typename T2>
    class Add<int,T2>{
    public:
    	Add();
    	~Add();
    private:
    	int _left;
    	T2 _right;
    };
    
    //特化指针类型
    template<typename T1,typename T2>
    class Add<T1*,T2*>{
    public:
    	Add();
    	~Add();
    private:
    	T1 _left;
    	T2 _right;
            T1* _leftPtr;
            T2* _rightPtr;
    };
    

      我们从上述代码可以看出,偏特化具有这样的特性:

      偏特化并不仅仅局限于特化部分参数,而是对模板参数更进一步的条件限制所设定出来的一个特化版本.

      最后的说明:

      特化并不只是类模板才具有的特性,函数模板也具有特化功能,函数模板的特化与类模板类似.

  • 相关阅读:
    双指针
    git .gitignore文件修改后不生效
    Vue路由跳转携带固定参数
    GitLab 安装说明
    安装 PostgreSQL
    职场软素质&算法工程师的硬素质卓越的职场人需要的42种能力
    内存泄漏排查
    Oracle基本操作(登陆、用户、表空间、exp/imp、权限)
    oracle删除用户、表空间及数据⽂件⽅法
    oracle检查存储过程出错原因
  • 原文地址:https://www.cnblogs.com/qq329914874/p/6729223.html
Copyright © 2020-2023  润新知