zoukankan      html  css  js  c++  java
  • 模版 template 的用法

    模版类的用法转自: http://www.cnblogs.com/this-543273659/archive/2011/07/21/2112358.html

    1.类模板与模板类的概念

    ⑴ 什么是类模板 一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员、默写成员函数的参数、某些成员函数的返回值,能够取任意类型(包括系统预定义的和用户自定义的)。

      如果一个类中数据成员的数据类型不能确定,或者是某个成员函数的参数或返回值的类型不能确定,就必须将此类声明为模板,它的存在不是代表一个具体的、实际的类,而是代表着一类类。

    ⑵ 类模板定义 定义一个类模板,一般有两方面的内容:

    A.       首先要定义类,其格式为:

    template <typename T>  (或是用class 关键字,即 template  <class T>. 二者完全等价,只是typename更形象些,但早期版本的C++编译器可能识别不出)。还是推荐使用typename.

    class foo

    {

    ……

    }

    foo 为类名,在类定义体中,如采用通用数据类型的成员,函数参数的前面需加上T,其中通用类型T可以作为普通成员变量的类型,还可以作为const和static成员变量以及成员函数的参数和返回类型之用。例如:

    template<typename T>

    class Test{

    private:

        T n;

        const T i;

        static T cnt;

    public:

        Test():i(0){}

        Test(T k);

        ~Test(){}

        void print();

        T operator+(T x);

    };

    B.       在类定义体外定义成员函数时,若此成员函数中有模板参数存在,则除了需要和一般类的体外定义成员函数一样的定义外,还需在函数体外进行模板声明

    例如

    template<typename T>

    void Test<T>::print(){

        std::cout<<"n="<<n<<std::endl;

        std::cout<<"i="<<i<<std::endl;

        std::cout<<"cnt="<<cnt<<std::endl;

     

    }

    如果函数是以通用类型为返回类型,则要在函数名前的类名后缀上“<T>”。例如:

    template<typename T>

    Test<T>::Test(T k):i(k){n=k;cnt++;}

    template<typename T>

    T Test<T>::operator+(T x){

                   return n + x;

                   }

    C.       在类定义体外初始化const成员和static成员变量的做法和普通类体外初始化const成员和static成员变量的做法基本上是一样的,唯一的区别是需在对模板进行声明,例如

    template<typename T>

    int Test<T>::cnt=0;

    template<typename T>

    Test<T>::Test(T k):i(k){n=k;cnt++;}

    ⑶ 类模板的使用 类模板的使用实际上是将类模板实例化成一个具体的类,它的格式为:类名<实际的类型>

    但 定义类模板的时候,如果.h文件和.cpp文件分离,在main.cpp中使用的话会产生“error LNK2019: unresolved external symbol”错误。

    类模板错误 error LNK2019: unresolved external symbol

    原因是:连接之前,编译器会把没有定义的函数进行标记,然后通过连接器来找到相应函数的定义。然而在对类模板进行编译的时候,头文件中的类型<T>被实例化为相应的类型,而cpp文件中的T还是T,并没有实例化,所以在连接的时候就产生了如上问题。

    解决方法有3种:

    1.把类模板的声明和定义放在同一个文件中。

    2.在类模板的cpp文件中进行详细声明(explicit instantiation)。例如要实例化一个int型的类,就加上如下语句:template class classname<int>;

    3.在include的时候不是包含.h文件,而是.cpp文件:#include "templateclass.cpp"

    模板类

    模板类是一个具体的类,它是类模板实例化后的一个产物。说个形象点的例子吧。我把类模板比作一个做饼干同的模子,而模板类就是用这个模子做出来的饼干,至于这个饼干是什么味道的就要看你自己在实例化时用的是什么材料了,你可以做巧克力饼干,也可以做豆沙饼干,这些饼干的除了材料不一样外,其他的东西都是一样的了。

    2.类模板的派生

      可以从类模板派生出新的类,既可以派生类模板,也可以派生非模板类。派生方法:

    ⑴ 从类模板派生类模板可以从类模板派生出新的类模板,它的派生格式如下例所示:

    template <typename T>

    class base

    {

    ……

    };

     

    template <typename T>

    class derive:public base<T>

    {

    ……

    };

    与一般的类派生定义相似,只是在指出它的基类时要缀上模板参数,即base<T>。

    ⑵ 从类模板派生非模板类  可以从类模板派生出非模板类,在派生中,作为非模板类的基类,必须是类模板实例化后的模板类,并且在定义派生类前不需要模板声明语句:template<class>。例如:

    template <typename T>

    class base

    {

    ……

    };

     

    class derive:public base<int>

    {

    ……

    };

    在定义derive类时,base已实例化成了int型的模板类。

  • 相关阅读:
    在SharePoint 2010中创建网站的权限级别
    SharePoint 2013 Pop-Up Dialogs
    SharePoint 2010 Pop-Up Dialogs
    sharepoint 2010 页面添加footer方法 custom footer for sharepoint 2010 master page
    Using SharePoint 2010 dialogs
    Spring Security
    mysql优化
    memcached缓存技术
    网页静态化技术
    最小生成树
  • 原文地址:https://www.cnblogs.com/wenshanzh/p/2789142.html
Copyright © 2011-2022 走看看