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

    千次阅读 2018-08-03 11:31:18
    什么是类模板?  模板的目的就是为了淡化数据类型的要求,作出通用数据类型的模板。类中的成员变量和成员函数都牵涉到了数据类型。  在成员函数、成员变量以及基类中包含有类型参数的类称为类模板。  和函数...

    什么是类模板?

           模板的目的就是为了淡化数据类型的要求,作出通用数据类型的模板。类中的成员变量和成员函数都牵涉到了数据类型。

           在成员函数、成员变量以及基类中包含有类型参数的类称为类模板。

           和函数模板一样,类模板只是一个模板,并不是真正的类。

    形式:template<class T1, class T2, ... ,class Tn>
              class className
              { ... };

     

    类模板与函数模板的异同

    类模板和函数模板都需要二次编译

          我们看到函数模板的原理是二次编译。同样的类模板也需要二次编译。

    类模板 -- 实例化为 -> -- 实例化为 -> 对象

           类模板先在编译期的时候实例化为类,再在运行的时候实例化为真正的对象。其实类中的这个二次编译也叫二次实例化。

    类不能隐式推断

    我们在上一篇中讲到了函数模板的隐式推断,但是类模板却不能隐式推断。

     

    class_template.cpp

    #include <iostream>
    using namespace std;
    
    template <typename T>           //声明
    class Complex;
    
    template <typename T>           
    ostream &operator << (ostream &out, const Complex<T> &c);
    
    
    
    //模板类
    template <typename T>             //作用域很小
    class Complex
    {
    	friend ostream &operator << <T> (ostream &out, const Complex<T> &c);   
    	//将该函数声明成模板函数 
    	/*
    	friend ostream &operator << (ostream &out,const Complex<T> &c)    //全局函数可以在类的内部实现
    	{
    		out << c.m_a << "+" << c.m_b << "i" ;
    		return out;
    	}
    	*/
    private:
    	T m_a;
    	T m_b;
    public:
    	Complex(T a, T b);
    	void print();
    };
    
    template <typename T>
    Complex<T>::Complex(T a, T b)          //函数放在外面需要在Complex后面加上<T>
    {
    	m_a = a;
    	m_b = b;
    }
    
    template <typename T>
    void Complex<T>::print()
    {
    	cout << m_a << "+" << m_b << "i" << endl;
    }
    
    //该函数放在外面就要系很多声明
    template <typename T> 
    ostream &operator << (ostream &out, const Complex<T> &c)  //Complex是模板类
    {
    	out << c.m_a << "+" << c.m_b << "i" ;
    	return out;
    }
    
    
    int main()
    {
    	Complex<int> c(1, 2);    //类模板是一定要显式调用的
    	//c.print();
    	
    	cout << c << endl;
    	
    	return 0;
    }

     

    #include <iostream>
    using namespace std;
    
    
    template <typename T>
    class A                      //模板类
    {
    private:
    	T m_a;
    public:
    	A(T a);
    	//void print();
    };
    
    template <typename T>
    A<T>::A(T a)
    {
    	m_a = a;
    }
    
    
    class B : public A<int>     //模板类派生普通类
    {
    private:
    	int m_b;
    public:
    	B(int b);
    	
    };
    
    B::B(int b) : A<int>(1)     //一定要显式调用
    {
    	m_b = b;
    }
    
    
    template <typename T ,typename T2>
    class C : public A<T2>      //模板类派生模板类
    {
    private:
    	T m_c;
    public:
    	C(T c, T2 a);
    };
    
    template <typename T ,typename T2>
    C<T, T2>::C(T c, T2 a) : A<T2>(a)      //也要显式调用
    {
    	m_c = c;
    }
    
    
    int main()
    {
    	B b(1);
    	C<int, double> c(1,2.57);
    	
    	return 0;
    }
    

     

     

    展开全文
  • C++类模板 template 详细使用方法

    千次阅读 多人点赞 2017-11-27 21:48:30
    C++类模板 template 详细使用方法 类模板与函数模板的定义和使用类似。 有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,如下面语句声明了一个类: class Compare_int { public : Compare(int a,...
    C++类模板 template <class T>详细使用方法
    类模板与函数模板的定义和使用类似。
    有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,如下面语句声明了一个类:
    class Compare_int
    {
    public :
       Compare(int a,int b)
       {
          x=a;
          y=b;
       }
       int max( )
       {
          return (x>y)?x:y;
       }
       int min( )
       {
          return (x<y)?x:y;
       }
    private :
       int x,y;
    };
    其作用是对两个整数作比较,可以通过调用成员函数max和min得到两个整数中的大者和小者。
    如果想对两个浮点数(float型)作比较,需要另外声明一个类:
    class Compare_float
    {
    public :
       Compare(float a,float b)
       {
          x=a;y=b;
       }
       float max( )
       {
          return (x>y)?x:y;
       }
       float min( )
       {
          return (x<y)?x:y;
       }
    private :
       float x,y;
    }
    显然这基本上是重复性的工作,应该有办法减少重复的工作。
    C++在发展的后期增加了模板(template )的功能,提供了解决这类问题的途径。可以声明一个通用的类模板,它可以有一个或多个虚拟的类型参数,如对以上两个类可以综合写出以下的类模板:
    template <class numtype> //声明一个模板,虚拟类型名为numtype
    class Compare //类模板名为Compare
    {
    public :
       Compare(numtype a,numtype b)
       {
          x=a;y=b;
       }
       numtype max( )
       {
          return (x>y)?x:y;
       }
       numtype min( )
       {
          return (x<y)?x:y;
       }
    private :
       numtype x,y;
    };
    请将此类模板和前面第一个Compare_int类作一比较,可以看到有两处不同。

    1) 声明类模板时要增加一行
        template <class 类型参数名>
    template意思是“模板”,是声明类模板时必须写的关键字。在template后面的尖括号内的内容为模板的参数表列,关键字class表示其后面的是类型参数。在本例中numtype就是一个类型参数名。这个名宇是可以任意取的,只要是合法的标识符即可。这里取numtype只是表示“数据类型”的意思而已。此时,mimtype并不是一个已存在的实际类型名,它只是一个虚拟类型参数名。在以后将被一个实际的类型名取代。

    2) 原有的类型名int换成虚拟类型参数名numtype。
    在建立类对象时,如果将实际类型指定为int型,编译系统就会用int取代所有的numtype,如果指定为float型,就用float取代所有的numtype。这样就能实现“一类多用”。

    由于类模板包含类型参数,因此又称为参数化的类。如果说类是对象的抽象,对象是类的实例,则类模板是类的抽象,类是类模板的实例。利用类模板可以建立含各种数据类型的类。

    那么,在声明了一个类模板后,怎样使用它呢?怎样使它变成一个实际的类?

    先回顾一下用类来定义对象的方法:
        Compare_int cmp1(4,7); // Compare_int是已声明的类
    其作用是建立一个Compare_int类的对象,并将实参4和7分别赋给形参a和b,作为进 行比较的两个整数。

    用类模板定义对象的方法与此相似,但是不能直接写成
       Compare cmp(4,7); // Compare是类模板名
    Compare是类模板名,而不是一个具体的类,类模板体中的类型numtype并不是一个实际的类型,只是一个虚拟的类型,无法用它去定义对象。必须用实际类型名去取代虚拟的类型,具体的做法是:
        Compare <int> cmp(4,7);
    即在类模板名之后在尖括号内指定实际的类型名,在进行编译时,编译系统就用int取代类模板中的类型参数numtype,这样就把类模板具体化了,或者说实例化了。这时Compare<int>就相当于前面介绍的Compare_int类。
    [例] 声明一个类模板,利用它分别实现两个整数、浮点数和字符的比较,求出大数和小数。
    #include <iostream>
    using namespace std;
    template <class numtype>
    //定义类模板
    class Compare
    {
       public :
       Compare(numtype a,numtype b)
       {x=a;y=b;}
       numtype max( )
       {return (x>y)?x:y;}
       numtype min( )
       {return (x<y)?x:y;}
       private :
       numtype x,y;
    };
    int main( )
    {
       Compare<int > cmp1(3,7);  //定义对象cmp1,用于两个整数的比较
       cout<<cmp1.max( )<<" is the Maximum of two integer numbers."<<endl;
       cout<<cmp1.min( )<<" is the Minimum of two integer numbers."<<endl<<endl;
       Compare<float > cmp2(45.78,93.6);  //定义对象cmp2,用于两个浮点数的比较
       cout<<cmp2.max( )<<" is the Maximum of two float numbers."<<endl;
       cout<<cmp2.min( )<<" is the Minimum of two float numbers."<<endl<<endl;
       Compare<char> cmp3(′a′,′A′);  //定义对象cmp3,用于两个字符的比较
       cout<<cmp3.max( )<<" is the Maximum of two characters."<<endl;
       cout<<cmp3.min( )<<" is the Minimum of two characters."<<endl;
       return 0;
    }

    运行结果如下:
    7 is the Maximum of two integers.
    3 is the Minimum of two integers.

    93.6 is the Maximum of two float numbers.
    45.78 is the Minimum of two float numbers.

    a is the Maximum of two characters.
    A is the Minimum of two characters.

    还有一个问题要说明: 上面列出的类模板中的成员函数是在类模板内定义的。如果改为在类模板外定义,不能用一般定义类成员函数的形式:
        numtype Compare::max( ) {…} //不能这样定义类模板中的成员函数
    而应当写成类模板的形式:
        template <class numtype>
        numtype Compare<numtype>::max( )
        {
            return (x>y)?x:y;
        }
    上面第一行表示是类模板,第二行左端的numtype是虚拟类型名,后面的Compare <numtype>是一个整体,是带参的类。表示所定义的max函数是在类Compare <numtype>的作用域内的。在定义对象时,用户当然要指定实际的类型(如int),进行编译时就会将类模板中的虚拟类型名numtype全部用实际的类型代替。这样Compare <numtype >就相当于一个实际的类。大家可以将例9.14改写为在类模板外定义各成员 函数。

    归纳以上的介绍,可以这样声明和使用类模板:
    1) 先写出一个实际的类。由于其语义明确,含义清楚,一般不会出错。

    2) 将此类中准备改变的类型名(如int要改变为float或char)改用一个自己指定的虚拟类型名(如上例中的numtype)。

    3) 在类声明前面加入一行,格式为:
        template <class 虚拟类型参数>
    如:
        template <class numtype> //注意本行末尾无分号
        class Compare
        {…}; //类体

    4) 用类模板定义对象时用以下形式:
        类模板名<实际类型名> 对象名;
        类模板名<实际类型名> 对象名(实参表列);
    如:
        Compare<int> cmp;
        Compare<int> cmp(3,7);

    5) 如果在类模板外定义成员函数,应写成类模板形式:
       template <class 虚拟类型参数>
       函数类型 类模板名<虚拟类型参数>::成员函数名(函数形参表列) {…}

    关于类模板的几点说明:
    1) 类模板的类型参数可以有一个或多个,每个类型前面都必须加class,如:
        template <class T1,class T2>
        class someclass
        {…};
    在定义对象时分别代入实际的类型名,如:
        someclass<int,double> obj;

    2) 和使用类一样,使用类模板时要注意其作用域,只能在其有效作用域内用它定义对象。

    3) 模板可以有层次,一个类模板可以作为基类,派生出派生模板类。有关这方面的知识实际应用较少,本教程暂不作介绍,感兴趣的同学可以自行学习。

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

    万次阅读 多人点赞 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++知识目录

    展开全文
  • 一、函数模板 template.h #pragma once #include <iostream> #include <map> template <typename T> T funcadd(T a, T b) { T addhe = a + b; return addhe; } template <typename T, ...

    一、函数模板

    template.h

    #pragma once
    #include <iostream>
    #include <map>
    
    template <typename T>
    T funcadd(T a, T b)
    {
    	T addhe = a + b;
    	return addhe;
    }
    
    template <typename T, int a, int b=7>
    int funcadd1(T c)
    {
    	int addhe = (int)c + a + b;
    	return addhe;
    }
    
    template <typename T>
    typename T::size_type getLength(const T &c)//typedef int string:size_type,T::size_type是一个类型,所以前面要加上typename
    {
    	if (c.empty())
    		return 0;
    	return c.size();
    }
    
    template <typename T1, typename T2, typename T3>
    T1 sum(T2 i, T3 j)
    {
    	T1 result = i + j;
    	return result;
    }

    main.cpp

    #include <iostream>
    #include "template.h"
    using namespace std;
    int main()
    {
        cout << "Hello World!\n";
    	funcadd(5, 6);
    	funcadd1<int, 5, 6>(7);//必须强行指定类型
    	string mytest = "I love China";
    	string::size_type size = getLength(mytest);
    	sum<int>(22, 33);//必须强行指定类型
    }

    函数模板:默认自行推倒类型,如需要,可强行指定。

     

    二、类模板、类成员函数模板

    template.h

    #pragma once
    #include <iostream>
    #include <map>
    
    template <typename C>
    class A
    {
    public:
    	template <typename T2>
    	A(T2 v1, T2 v2);
    
    	template <typename T>
    	void myft(T tmft);
    };
    
    template <typename C>
    template <typename T2>
    A<C>::A(T2 v1, T2 v2)
    {
    
    }
    
    template <typename C>
    template <typename T>
    void A<C>::myft(T tmft)
    {
    	std::cout << tmft << std::endl;
    }

    main.cpp

    #include <iostream>
    #include "template.h"
    using namespace std;
    int main()
    {
    	A<float> a(1.3f, 1.4f);
    	a.myft(3);
    	return 1;
    }
    

    模板类声明和类定义必须在同一个.h文件中。

    展开全文
  • struct NODE//就是这个类模板出错 { V element; NODE *next; NODE *prv; NODE(const V & k):element(k){} }; private: NODE<T> *start; NODE<T> *end; int num; LIST(const LIST &l) {} ...
  • C++类模板派生类模板

    2019-01-29 23:05:09
    #include "pch.h" #include &lt;iostream&gt; using namespace std; template&lt;class T&gt; class Animal { public: void Jiao() { cout &lt;&... public
  • C++类模板和模板类

    万次阅读 多人点赞 2018-11-29 14:32:35
    C++通过类模板来实现泛型支持。 1 基础的类模板 类模板,可以定义相同的操作,拥有不同数据类型的成员属性。 通常使用template来声明。告诉编译器,碰到T不要报错,表示一种泛型. 如下,声明一个普通的类模板: ...
  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多...
  • 类模板与模板类概念区分

    千次阅读 2019-04-27 09:53:37
    类模板的定义: 允许用户为类定义个一种模式,使得类中的某些数据成员、默认成员函数的参数,某些成员函数的返回值,能够取任意类型 (它是一个参数未确定的模板) template<typename T> class A{}; ...
  • 这期间有涉及到函数模板与模板函数,类模板与模板类的概念 (类似于类与类对象的区别) 注意:模板类的函数声明和实现必须都在头文件中完成,不能像普通类那样声明在.h文件中,实现在.cpp文件中。 1、函数模板和...
  • 一、类模板全特化、偏特化 #pragma once #include <iostream> #include <map> template <typename T, typename U> class TC { public: TC() { std::cout << "泛化版本构造函数" <...
  • C++类模板

    千次阅读 2020-01-27 12:08:20
    C++类模板 模板是C++的高级特性,分为函数模板和类模板。 使用模板能够快速建立里具有类型安全的类库集合和函数集合。 关于函数模板的学习————》》C++函数模板 本文主要介绍类模板。 使用template关键字不但可以...
  • 类模板和模板类的定义

    千次阅读 2019-05-09 13:03:45
    https://www.cnblogs.com/cxq0017/p/6076856.html 模板类就是在定义函数中参数类型时 定义一个未知类型 而类模板就是在写类的时候定义几个未知参数类型然后进行应用 谢谢上文中的博主 ...
  • 模板类与类模板、函数模板与模板函数等的区别 函数指针 = 指向函数的指针 指针函数=返回指针的函数 数组指针=指向数组的指针 指针数组=内容是指针的数组 类模板=用来产生类的模板 模板类=使用类模板产生的类...

空空如也

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

类模板