美文网首页C/C++程序设计专题散文摄影
C++系列 --- 类模板概念,类模板定义和使用

C++系列 --- 类模板概念,类模板定义和使用

作者: 307656af5a04 | 来源:发表于2019-05-04 17:18 被阅读209次

    今天呢,我们一起来学习下模板与泛型中的知识点,类模板的概念,类模板的定义与使用,希望大家通过本节的学习,可以对类模板有一个清晰的理解!

    1、概述

    用类模板来实例化一个特定的类;

    编译器不能为类模板推断模板参数类型,所以为了使用类模板,我们必须在模板名后面用<>来提供额外的信息,这些信息其实就是对应着模板类参数列表里面的参数;

    类模板实现同一套代码,可以应付不同的数据类型,这样就显得精简多了。

    2、类模板定义

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

    实例
    myvector类模板 模仿vector

    实例化类模板的时候,必须有类的全部信息,包括类模板中成员函数的函数体;

    myvector.h文件

    #ifndef __MYVECTOR__
    #define __MYVECTOR__
    
    // 定义类模板
    // 名字为T的模板参数,
    // 用来表示myvector这个容器
    // 所保存的元素类型
    template<typename T>  
    class myvector
    {
    public:
        // 迭代器 vector iterator
        typedef T* myiterator;  
    
    public:
        // 构造函数
        myvector(); 
    
        // 赋值运算符重载,在类模板内部使用模板名,
        // 并不需要提供模板参数
        myvector& operator=(const myvector&);  
        //myvector<T>& operator=(const myvector<T>&);
    
    public:
        // 迭代器的起始位置
        myiterator mybegin();  
        // 迭代器的最后一个元素的下一个位置
        myiterator myend(); 
    
        //类模板的成员函数
    public:
        // 把函数的函数体(函数具体实现)
        // 放在类模板的定义中
        //void myfunc() {}; 
    
        void myfunc();
    };
    
    // 类模板函数在类外部实现
    template<typename T>
    void myvector<T>::myfunc()
    {
        // ......
        return;
    }
    
    // 重载赋值运算符,<T>表示
    // 返回的是一个实例化了的myvector
    template<typename T>
    myvector<T>& myvector<T>::operator=(const myvector&)
    {
        return *this;
    }
    
    #endif
    

    main.cpp文件

    #include <iostream>
    #include "myvector.h"
    
    using namespace std;
    
    int main(int argc, char** argv)
    {
        // 这个时候,编译器给生成一个具体的类
        myvector<int> tmpvec1;  
        myvector<double> tmpvec2;
        myvector<string> tmpvec2;
    }
    

    myvector是类模板名,它不是一个类名,类模板是用来实例化类类型的;所以myvector<int>,myvector<double>才是类型名(实例化的类型);所以,一个实例化的类型,总会用尖括号<>包含着模板参数。

    3、类模板的成员函数

    类模板成员函数,可以写在类模板定义中,这种写在类模板定义中的函数会被隐式的声明为inline函数;

    类模板被实例化之后,模板的每个实例都会有自己版本的成员函数,所以,类模板的成员函数具有和这个类模板相同的模板参数;

    如果你把类模板成员函数的定义写在类模板的外边,那么这个成员函数的模板参数就必须体现出来;

    定义在类模板之外的成员函数必须以关键字template开头,后面接类模板参数列表,同时,在类名后面要用尖括号<>把模板参数列表里面的所有模板参数名列出来,如果是多个模板参数,用逗号分隔;

    类外实现成员函数的定义

    // 类模板函数在类外部实现
    template<typename T>
    void myvector<T>::myfunc()
    {
        // ......
        return;
    }
    

    一个类模板虽然肯能有很多的成员函数,但是,当你实例化模板之后,如果你后续没有使用到某个函数,则这个成员函数不会被实例化,说白了,就是一个实例化的模板,它的成员函数只有在使用的时候才被实例化。

    4、模板类名字的使用

    // 类模板名字的使用,即T的使用
    // 重载赋值运算符,<T>表示
    // 返回的是一个实例化了的myvector
    template<typename T>
    myvector<T>& myvector<T>::operator=(const myvector&)
    {
        return *this;
    }
    

    5、非类型模板参数

    实例:
    myarray.h文件

    #ifndef __MYARRAY__
    #define __MYARRAY__
    
    template<typename T,int size = 10>
    class myarray
    {
    
    private:
        T arr[size];
    
    public:
        void myfunc();
    
    };
    template<typename T, int size>
    void myarray<T,size>::myfunc()
    {
        cout << size << endl;
        return;
    }
    #endif
    

    int size = 10,即为非类型模板参数

    main.cpp文件

    #include <iostream>
    #include "myarray.h"
    
    using namespace std;
    
    int main(int argc, char** argv)
    {
        myarray<int, 100> tmparray1;
        tmparray1.myfunc();  // 100
    
        myarray<int> tmparray2;
        tmparray2.myfunc(); //10
    
        system("pause");
        return 0;
    }
    

    实验结果

    实验结果

    非类型模板参数的一些限制:
    (1)浮点型不能左非类型模板参数,比如float,double
    (2)类类型一般也不允许左非类型模板参数

    好了,今天的C++模板与泛型学到这里就结束了,希望大家可以认真理解哦!!

    我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C需要编程,C++需要编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!

    相关文章

      网友评论

        本文标题:C++系列 --- 类模板概念,类模板定义和使用

        本文链接:https://www.haomeiwen.com/subject/kginnqtx.html