精华内容
参与话题
问答
  • 模板类

    千次阅读 2018-09-05 10:55:31
    C++通过类模板来实现泛型支持。 1 基础的类模板 类模板,可以定义相同的操作,拥有不同数据类型的成员属性。 通常使用template来声明。告诉编译器,碰到T不要报错,表示一种泛型. 如下,声明一个普通的类模板: ...

    C++中有一个重要特性,那就是模板类型。类似于Objective-C中的泛型。C++通过类模板来实现泛型支持。

    1 基础的类模板

    类模板,可以定义相同的操作,拥有不同数据类型的成员属性。

    通常使用template来声明。告诉编译器,碰到T不要报错,表示一种泛型.

    如下,声明一个普通的类模板:

    template <typename T>
    class Complex{
        
    public:
        //构造函数
        Complex(T a, T b)
        {
            this->a = a;
            this->b = b;
        }
        
        //运算符重载
        Complex<T> operator+(Complex &c)
        {
            Complex<T> tmp(this->a+c.a, this->b+c.b);
            return tmp;
        }
            
    private:
        T a;
        T b;
    }
    
    int main()
    {
        //对象的定义,必须声明模板类型,因为要分配内容
        Complex<int> a(10,20);  
        Complex<int> b(20,30);
        Complex<int> c = a + 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;
    };
    
    

    3 内部声明定义普通模板函数和友元模板函数

    普通模板函数和友元模板函数,声明和定义都写在类的内部,也不会有什么报错。正常。

    template <typename T>
    class Complex {
        
        //友元函数实现运算符重载
        friend ostream& operator<<(ostream &out, Complex &c)
        {
            out<<c.a << " + " << c.b << "i";
            return out;
        }
        
    public:
        Complex(T a, T b)
        {
            this->a = a;
            this->b = b;
        }
        
        //运算符重载+
        Complex operator+(Complex &c)
        {
            Complex temp(this->a + c.a, this->b + c.b);
            return temp;
        }
        
        //普通加法函数
        Complex myAdd(Complex &c1, Complex &c2)
        {
            Complex temp(c1.a + c2.a, c1.b + c2.b);
            return temp;
        }
        
    private:
        T a;
        T b;
    };
    
    int main()
    {
        Complex<int> c1(1,2);
        Complex<int> c2(3,4);
        
        Complex<int> c = c1 + c2;
        
        cout<<c<<endl;
        
        return 0;
    }
    

    4 内部声明友元模板函数+外部定义友元模板函数

    如果普通的模板函数声明在内的内部,定义在类的外部,不管是否处于同一个文件,就跟普通的函数一样,不会出现任何错误提示。但是如果是友元函数就会出现报错,是因为有二次编译这个机制存在。

    4.1 模板类和模板函数的机制

    在编译器进行编译的时候,编译器会产生类的模板函数的声明,当时实际确认类型后调用的时候,会根据调用的类型进行再次帮我们生成对应类型的函数声明和定义。我们称之为二次编译。同样,因为这个机制,会经常报错找不到类的函数的实现。在模板类的友元函数外部定义时,也会出现这个错误。解决方法是 “ 类的前置声明和函数的前置声明 ”。

    按照普通模板函数的样式处理友元函数

    
    #include <iostream>
    using namespace std;
    
    
    template <typename T>
    class Complex {
        
        //友元函数实现运算符重载
        friend ostream& operator<<(ostream &out, Complex<T> &c);
        
    public:
        Complex(T a, T b);
        
        //运算符重载+
        Complex<T> operator+(Complex<T> &c);
        
        //普通加法函数
        Complex<T> myAdd(Complex<T> &c1, Complex<T> &c2);
        
    private:
        T a;
        T b;
    };
    
    //友元函数的实现
    template <typename T>
    ostream& operator<<(ostream &out, Complex<T> &c)
    {
        out<<c.a << " + " << c.b << "i";
        return out;
    }
    
    
    //函数的实现
    template <typename T>
    Complex<T>::Complex(T a, T b)
    {
        this->a = a;
        this->b = b;
    }
    
    template <typename T>
    Complex<T> Complex<T>::operator+(Complex<T> &c)
    {
        Complex temp(this->a + c.a, this->b + c.b);
        return temp;
    }
    
    template <typename T>
    Complex<T> Complex<T>::myAdd(Complex<T> &c1, Complex<T> &c2)
    {
        Complex temp(c1.a + c2.a, c1.b + c2.b);
        return temp;
    }
    
    
    int main()
    {
        Complex<int> c1(1,2);
        Complex<int> c2(3,4);
        
        Complex<int> c = c1 + c2;
        
        cout<<c<<endl;
        
        return 0;
    }
    
    
    
    

    友元函数的定义写在类的外部--错误信息

    Undefined symbols for architecture x86_64:
      "operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Complex<int>&)", referenced from:
          _main in demo1.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    上面的错误信息,就是典型的二次编译的错误信息,找不到友元函数的函数实现。所以,如果友元模板函数的定义写在函数的外部,需要进行类和函数的前置声明,来让编译器找到函数的实现

    4.2 前置声明解决二次编译问题

    • 类的前置声明
    • 友元模板函数的前置声明
    • 友元模板函数声明需要增加泛型支持

    前置声明.png

    5 声明和定义分别在不同的文件(模板函数、模板友元)

    类的声明和实现,分别在不同的文件下,需要增加一个hpp文件支持。或者尽量将模板函数与模板友元放在一个文件下。

    • 类的声明与函数的声明写在.h文件
    • 类的实现及函数的实现写在.cpp文件
    • 将.cpp文件改成.hpp文件
    • 在主函数中调用.hpp文件,而不是引用.h文件

    如果碰到.h和.hpp文件都存在的情况下,引用.hpp文件。

    demo2.h文件

    存放类的声明和函数的声明

    #include <iostream>
    using namespace std;
    
    //类的前置声明
    template <typename T>
    class Complex;
    
    //友元函数的声明
    template <typename T>
    ostream& operator<<(ostream &out, Complex<T> &c);
    
    template <typename T>
    class Complex {
        
        //友元函数实现运算符重载
        friend ostream& operator<< <T> (ostream &out, Complex<T> &c);
        
    public:
        Complex(T a, T b);
        
        //运算符重载+
        Complex<T> operator+(Complex<T> &c);
        
        //普通加法函数
        Complex<T> myAdd(Complex<T> &c1, Complex<T> &c2);
        
    private:
        T a;
        T b;
    };
    
    

    demo2.hpp文件

    包括模板函数的实现

    
    #include "demo2.h"
    
    //友元函数的实现
    template <typename T>
    ostream& operator<<(ostream &out, Complex<T> &c)
    {
        out<<c.a << " + " << c.b << "i";
        return out;
    }
    
    
    //函数的实现
    template <typename T>
    Complex<T>::Complex(T a, T b)
    {
        this->a = a;
        this->b = b;
    }
    
    template <typename T>
    Complex<T> Complex<T>::operator+(Complex<T> &c)
    {
        Complex temp(this->a + c.a, this->b + c.b);
        return temp;
    }
    
    template <typename T>
    Complex<T> Complex<T>::myAdd(Complex<T> &c1, Complex<T> &c2)
    {
        Complex temp(c1.a + c2.a, c1.b + c2.b);
        return temp;
    }
    
    
    

    main.cpp文件

    需要调用hpp文件

    
    #include <iostream>
    using namespace std;
    #include "demo2.hpp"
    
    
    int main()
    {
        Complex<int> c1(1,2);
        Complex<int> c2(3,4);
        
        Complex<int> c = c1 + c2;
        
        cout<<c<<endl;
        
        return 0;
    }
    
    

     



    作者:一月二十三
    链接:https://www.jianshu.com/p/70ca94872418
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    展开全文
  • 本文通过c++ primer plus中的例子来学习写模板类. 1.为什么需要模板类? 为了满足代码重用的需求. 比如stack类,希望不同的类型都能用. 先看看用typedef 定义的stack类. // stack.h -- class definition ...

    本文通过c++ primer plus中的例子来学习写模板类.

    1.为什么需要模板类?

    为了满足代码重用的需求.
    比如stack类,希望不同的类型都能用.
    先看看用typedef 定义的stack类.

    // stack.h -- class definition for the stack ADT
    #ifndef STACK_H_
    #define STACK_H_
    
    typedef unsigned long Item;
    class Stack
    {
    private:
        enum {MAX = 10};    // constant specific to class
        Item items[MAX];    // holds stack items
        int top;            // index for top stack item
    public:
        Stack();
        bool isempty() const;
        bool isfull() const;
        // push() returns false if stack already is full, true otherwise
        bool push(const Item & item);   // add item to stack
        // pop() returns false if stack already is empty, true otherwise
        bool pop(Item & item);          // pop top into item
    };
    Stack::Stack()    // create an empty stack
    {
        top = 0;
    }
    
    bool Stack::isempty() const
    {
        return top == 0;
    }
    
    bool Stack::isfull() const
    {
        return top == MAX;
    }
    
    bool Stack::push(const Item & item)   
    {
        if (top < MAX)
        {
            items[top++] = item;
            return true;
        }
        else
            return false;
    }
    
    bool Stack::pop(Item & item)
    {
        if (top > 0)
        {
            item = items[--top];
            return true;
        }
        else
            return false; 
    }
    #endif
    

    此时能操作的类型是unsigned long;现在如果希望stack还能够操作string,该怎么办呢?
    如果还用typedef定义,就要多一份类似的代码.
    这个时候模板类就发挥作用了.

    2.改写为模板类

    使用模板类改写stack如下

    // stacktp.h -- a stack template
    #ifndef STACKTP_H_
    #define STACKTP_H_
    template <class Type>
    class Stack
    {
    private:
        enum {MAX = 10};    // constant specific to class
        Type items[MAX];    // holds stack items
        int top;            // index for top stack item
    public:
        Stack();
        bool isempty();
        bool isfull();
        bool push(const Type & item); // add item to stack
        bool pop(Type & item);        // pop top into item
    };
    
    template <class Type>
    Stack<Type>::Stack()
    {
        top = 0;
    }
    
    template <class Type>
    bool Stack<Type>::isempty()
    {
        return top == 0;
    }
    
    template <class Type>
    bool Stack<Type>::isfull()
    {
        return top == MAX;
    }
    
    template <class Type>
    bool Stack<Type>::push(const Type & item)
    {
        if (top < MAX)
        {
            items[top++] = item;
            return true;
        }
        else
            return false;
    }
    
    template <class Type>
    bool Stack<Type>::pop(Type & item)
    {
        if (top > 0)
        {
            item = items[--top];
            return true;
        }
        else
            return false; 
    }
    
    #endif
    
    

    (1)将typedef替换为template <class Type>,关键字template告诉编译器要定义一个模板,尖括号内容相当于函数的参数列表.class相当于变量的类型名,Type相当于变量的值,变量接受类型作为其值.
    (2)使用泛型名Type替换标识符Item,Type是一个通用类型说明符,在使用模板是将使用实际类型替代它.
    (3)在每个函数前面使用模板声明template <class Type>打头.并且在类名后面要<Type>
    对比stack构造函数,未使用模板类前,

    Stack::Stack()    // create an empty stack
    {
        top = 0;
    }
    

    使用模板类后

    template <class Type>
    Stack<Type>::Stack()
    {
        top = 0;
    }
    

    3.使用

    使用的时候给类传递类型名就可以了

    Stack<int> kernels;
    Stack<string> colonels;
    

    4.模板中的非类型参数使用

    经常看到这样的模板定义,

    template <class T, int n>
    

    int n代表什么呢?此时该如何使用呢
    int n指出n的类型是int,这种类型称为非类型参数或者表达式参数.
    template <class T, int n>
    class ArrayTP
    以下的ArrayTP类如果按照
    ArrayTP<double,12> eggWeight的方式调用,表示用double替换T,12替换n.

    //arraytp.h  -- Array Template
    #ifndef ARRAYTP_H_
    #define ARRAYTP_H_
    
    #include <iostream>
    #include <cstdlib>
    
    template <class T, int n>
    class ArrayTP
    {
    private:
        T ar[n];
    public:
        ArrayTP() {};
        explicit ArrayTP(const T & v);
        virtual T & operator[](int i);
        virtual T operator[](int i) const;
    };
    
    template <class T, int n>
    ArrayTP<T,n>::ArrayTP(const T & v)
    {
        for (int i = 0; i < n; i++)
            ar[i] = v;
    }
    
    template <class T, int n>
    T & ArrayTP<T,n>::operator[](int i)
    {
        if (i < 0 || i >= n)
        {
            std::cerr << "Error in array limits: " << i
                << " is out of range\n";
            std::exit(EXIT_FAILURE);
        }
        return ar[i];
    }
    
    template <class T, int n>
    T ArrayTP<T,n>::operator[](int i) const
    {
        if (i < 0 || i >= n)
        {
            std::cerr << "Error in array limits: " << i
                << " is out of range\n";
            std::exit(EXIT_FAILURE);
        }
        return ar[i]; 
    }
    
    #endif
    
    展开全文
  • 类模板和模板类

    万次阅读 多人点赞 2019-07-04 21:10:42
    类模板和模板类 所谓类模板,实际上是建立一个通用类,其数据成员、成员函数的返回值类型和形参类型不具体指定,用一个虚拟的类型来代表。使用类模板定义对象时,系统会实参的类型来取代类模板中虚拟类型从而实现了...

    类模板和模板类

    所谓类模板,实际上是建立一个通用类,其数据成员、成员函数的返回值类型和形参类型不具体指定,用一个虚拟的类型来代表。使用类模板定义对象时,系统会实参的类型来取代类模板中虚拟类型从而实现了不同类的功能。

    定义一个类模板与定义函数模板的格式类似,必须以关键字template开始,后面是尖括号括起来的模板参数,然后是类名,其格式如下:

    template <typename 类型参数>
    class 类名{
           类成员声明 
    };
    
    或者
    
    template <class 类型参数>
    class 类名{
           类成员声明 
    };
    
    1. template:是一个声明模板的关键字,它表明声明一个模板

    2. 类型参数:通常用C++标识符表示,如T、Type等,实际上是一个虚拟的类型名,现在未指定它是哪一种具体的类型,但使用类模板时,必须将类型参数实例化。

    3. typename和class的作用相同,都是表示其后面的参数是一个虚拟的类名(即类型参数).

    在类声明中,欲采用通用数据类型的数据成员、成员函数的参数或返回类型前面需要加上类型参数。

    如建立一个用来实现求两个数最大值的类模板

    template<typename T>    //模板声明,其中T为类型参数
        class Compare{
          public:
           Compare(T i,T j)
           {
            x = i;
            y = j;
           }
           T max()
           {
            return (x>y)?x:y;
           } 
          private:
           T x,y; 
        };
    

    用类模板定义对象时,采用以下形式:

    类模板名<实际类型名>对象名[(实参表列)];
    

    因此,使用上面求最大值的类型模板的主函数可写成:

     int main()
         {
          Compare<int>com1(3,7);
          Compare<double>com2(12.34,56.78);
          Compare<char>com3('a','x');
          cout<<"其中的最大值是:"<<com1.max()<<endl;
          cout<<"其中的最大值是:"<<com2.max()<<endl;
          cout<<"其中的最大值是:"<<com3.max()<<endl;
          return  0;
         }    
    

    例6.6 类模板compare的使用举例

    #include<iostream.h>
    template<typename T>    //模板声明,其中T为类型参数
    class Compare{
      public:
        Compare(T i,T j)
        {
          x = i;
          y = j;
        }
        T max()
         {
          return (x>y)?x:y;
         } 
     private:
        T x,y; 
    };
    int main()
    {
    Compare<int>com1(3,7);                       //用类模板定义对象com1,此时T被int替代 
    Compare<double>com2(12.34,56.78);            //用类模板定义对象com2,此时T被double替代 
    Compare<char>com3('a','x');                  //用类模板定义对象com3,此时T被char替代 
    cout<<"其中的最大值是:"<<com1.max()<<endl;   
    cout<<"其中的最大值是:"<<com2.max()<<endl;
    cout<<"其中的最大值是:"<<com3.max()<<endl;
    return  0;
    }
    

    程序运行结果是:

    其中的最大值是:7
    其中的最大值是:56.78
    其中的最大值是:x        
    

    在以上例子中,成员函数(其中含有类型参数)是定义类体内的。但是,类模板中的成员函数,也可以在类模板外定义。此时,若成员函数中有参数类型存在,则C++有一些特殊的规定:

    (1)需要在成员函数定义之前进行模板声明;
    (2)在成员函数名前缀上"类名<类型参数>::";
    

    在类模板外定义成员函数的一般形式如下:

    temlate<typename 类型参数>
      函数类型 类名<类型参数>::成员函数名(形参表)
      {
        函数体; 
       }
       
       如上题中成员函数max在类模板外定义时,应该写成:
       template<typename T>
       T Compare<T>::max()
       {
        return (x>y)?x:y;
       } 
    

    //例6.7 在类模板外定义成员函数函数举例。

    #include<iostream.h>
    template<typename T>    //模板声明,其中T为类型参数
    class Compare{
      public:
        Compare(T i,T j)
        {
          x = i;
          y = j;
        }
        T max(); 
     private:
        T x,y; 
    };
    template<class T>
    T Compare<T>::max()
    {
     return (x>y)?x:y;
    }
    int main()
    {
    Compare<int>com1(3,7);                       //用类模板定义对象com1,此时T被int替代 
    Compare<double>com2(12.34,56.78);            //用类模板定义对象com2,此时T被double替代 
    Compare<char>com3('a','x');                  //用类模板定义对象com3,此时T被char替代 
    cout<<"其中的最大值是:"<<com1.max()<<endl;   
    cout<<"其中的最大值是:"<<com2.max()<<endl;
    cout<<"其中的最大值是:"<<com3.max()<<endl;
    return  0;
    } 
    

    /*
    程序运行结果是:

        其中的最大值是:7
        其中的最大值是:56.78
        其中的最大值是:x
    

    此例中,类模板Compare经实例化后生成了3个类型分别为int、double、char的模板类,这3个模板类
    经实例化后又生成了3个对象com1、com2、com3。类模板代表了一类类,模板类表示某一具体的类。关系如下:

                                             类模板
                                            Compare<T>
        实例化成模板类:Compare<int>       Compare<double>     Compare<char>
        实例化模板类对象:com1                 com2                com3
    

    例6.8 类模板Stack的使用举例。

    #include<iostream.h>
    const int size=10;
    template<class T>                     //模板声明,其中T为类型参数 
    class Stack{                          //类模板为Stack 
     public:
      void init()
      {
       tos=0;
      }
      void push(T ob);                    //声明成员函数push的原型,函数参数类型为T类型
      T pop();                            //声明成员函数pop的原型,其返回值类型为T类型
     private:
      T stack[size];                      //数组类型为T,即是自可取任意类型 
      int tos; 
    };
    template<class T>                     //模板声明 
    void Stack<T>::push(T ob)             //在类模板体外定义成员函数push 
    {
      if(tos==size)
       {
        cout<<"Stack is full"<<endl;
        return;
       }
      stack[tos]=ob;
      tos++; 
    }
    template<typename T>                  //模板声明 
    T Stack<T>::pop()                               //在类模板体外定义成员函数push
    {
      if(tos==0)
       {
        cout<<"Stack is empty"<<endl;
        return 0;
       }
      tos--; 
      return stack[tos];  
    }
    int main()
    {
     //定义字符堆栈 
     Stack<char> s1;                        //用类模板定义对象s,此时T被char取代
     s1.init();
     s1.push('a');
     s1.push('b');
     s1.push('c'); 
     for(int i=0;i<3;i++){cout<<"pop s1:"<<s1.pop()<<endl;}
     
     //定义整型堆栈 
     Stack<int> s2;                        //用类模板定义对象s,此时T被int取代
     s2.init();
     s2.push(1);
     s2.push(3);
     s2.push(5); 
     for(int i=0;i<3;i++){cout<<"pop s2:"<<s2.pop()<<endl;} 
     
     return 0; 
    }
    

    /*
    程序运行结果是:

    pop s1:c
    pop s1:b
    pop s1:a
    pop s2:5
    pop s2:3
    pop s2:1 
    

    说明:

    1. 在每一个类模板定义之前,都需要在前面加上模板声明,如

      template

      template
      并且,类模板在使用时,必须在模板类名字后面缀上<类型参数> ,如
      Stack

    2. 如同模板函数一样,模板类也可以有多个类型参数。

    例6.9 有两个类型参数的类模板举例

    #include<iostream.h>
    template<class QQ,class T>                    //声明模板,具有T1,T2两个类型参数 
    class Myclass{                                 //定义模板类Myclass 
      public:
       Myclass(QQ a,T b);
       void show();
      private:
       QQ x;
       T y;
    };
    template<typename QQ,typename T>
    Myclass<QQ,T>::Myclass(QQ a,T b)
    {
     x = a;
     y = b;
    }
    template<class QQ,class T>
    void Myclass<QQ,T>::show()
    {
     cout<<"x="<<x<<","<<"y="<<y<<endl;
    }
    int main()
    {
     Myclass <int,double>m1(12,0.15);               //用类模板定义对象m1,此时T1,T2分别被int、double取代 
     Myclass <int,char*>m2(12,"This a test.");      //用类模板定义对象m2,此时T1,T2分别被int,char*取代
    
     m1.show();
     m2.show();
     
     return 0; 
    }
    /*
    程序运行结果是:
    x=12,y=0.15
    x=12,y=This a test. 
    */
    

    程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!
    更多C++相关知识体系,请移步C++知识目录

    展开全文
  • 模板类派生模板类

    千次阅读 2016-09-27 08:21:39
    #include using namespace std; template class A { public: A(T a) { this->a = a; } void printA() { cout;...//模板派生是需要具体化模板类 c++编译器需要知道 父类的数据类型具体是什么
    #include <iostream>
    using namespace std;
    
    template<typename T>
    class A
    {
    public:
    	A(T a)
    	{
    		this->a = a;
    	}
    	void printA()
    	{
    		cout<<"a:"<<a<<endl;
    	}
    protected:
    private:
    	T a;
    };
    //模板派生是需要具体化模板类 c++编译器需要知道 父类的数据类型具体是什么样的(派生类首先调用父类的构造函数)
    //=====》要知道父类所占内存大小是多少,只有数据类型固定下来,才知道如何分配内存
    class B:public A<int>
    {
    public:
    	B():A(1)
    	{
    		this->a = 10;
    	}
    	void printA()
    	{
    		cout<<"a:"<<a<<endl;
    	}
    protected:
    private:
    	int a;
    };
    //类模板派生类模板
    template<typename T>
    class B2:public A<T>
    {
    public:
    	B2(T c, T d):A<T>(c)
    	{
    		this->c = c;
    		this->d = d;
    
    	}
    	void printC()
    	{
    		cout<<"c:"<<c<<endl;
    	}
    protected:
    private:
    	T c;
    	T d;
    };
    
    //类模板做函数参数
    
    void UseA(A<float> &a)
    {
    	a.printA();
    }
    
    int main()
    {
    
    	B2<int> b(1,2);
    	b.printC();
    
    	system("pause");
    	return 0;
    }

    展开全文
  • 类模板与模板类

    万次阅读 热门讨论 2009-02-15 17:23:00
    1.类模板与模板类的概念⑴ 什么是类模板 一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员、默写成员函数的参数、某些成员函数的返回值,能够取任意类型(包括系统预定义的和...
  • C++类模板和模板类

    万次阅读 多人点赞 2018-11-29 14:32:35
    C++通过类模板来实现泛型支持。 1 基础的类模板 类模板,可以定义相同的操作,拥有不同数据类型的成员属性。 通常使用template来声明。告诉编译器,碰到T不要报错,表示一种泛型. 如下,声明一个普通的类模板: ...
  •  模板类的继承是C++中较为高级的一种用法,其语法与普通C++类的继承略有差别。本文实例演示了一个通过C++模板类继承实现排序算法的案例。代码如下: 1. 实现List基类 #ifndef LIST_H #define LIST_H #include ...
  • 模板类模板类嵌套

    千次阅读 2019-01-11 11:36:53
    在C++中定义一个模板类,不能正确的定义move函数, template&lt;class T&gt; class List{ }; template&lt; class T&gt; class DoubleLinkList:public List&lt; T &gt; { private: /...
  • 类模板 与 模板类

    千次阅读 2014-09-11 20:46:33
    类模板表示的是一个模板,专门用于产生类的模子。...模板类指的是由一个模板生成而来的类。例如 Example p; Example p; Example p; template class EE :public Example { }; class EEE :public Example {
  • C++模板类

    千次阅读 2015-03-17 22:28:54
    类模板是对一批仅仅成员数据类型不同的的抽象,程序员只要为这一批所组成的整个家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的,(这可以看作是类模板的实例),从而大大提高编程的效率。...
  • 今天在看某c++框架源码时,发现模板类里的部分函数可以特例化,感觉很神奇便尝试了下,发现很多平时不会注意的c++细节及知识,写下来分享给大家,以便大家遇到相似问题时可以少踩点坑。 模板类会出现链接问题,编译...

空空如也

1 2 3 4 5 ... 20
收藏数 68,069
精华内容 27,227
关键字:

模板类