类模板(原创) - c++探索 - C++博客

来源:百度文库 编辑:神马文学网 时间:2024/04/29 13:12:26
            这几天看了下模板 ,以下是个人的些心得,高手见笑了
1.类模版 实例 对象定义 引起 实例化
                            指针,引用 不会引起实例化
类非型参数  只能是 整形,枚举,外联结,且应为一个常量编译时就应确定
                    浮点型,类类型,。。。都不可以
2.class templates 的成员函数 在调用和取地址时实例化,在类实例化时不会自动实例化
3.class templates 的友元申明
    a.非模版类型
          friend class man;
          friend void f(void);
           friend void man::f(void);
   b.一对一的模版友元
             friend class man;
             friend void f( man);
             friend void man::f();
    c.一对多的模版友元
          template
               friend class man;
           template
              friend void  f( T);
           template
              friend void man::f();
4.类模版的静态成员
      并不在模版定义时实例化,在类模版实例化时实例化,对应1个类型
template
int man::size=10;
而成员函数应为
  template
   void man::f(void)
{
..........................................
}
5.成员模版 可以是普通类和 模版类
如:
class woman                                            
{
public:
 template
  class man
 {
 public:
  print(T a)
  {
   cout<   
  }

 };
 template
  void print(T2 a)
 {
  cout< };
protected:
private:
};
                         1个好的例子
                           template    class A  
                                {      public:
                                                      template                
                                                      A&    operator =(const A & );
                               }
                               如此 则A 的对象 可以用其他型的对象赋值了
     在使用时才实例化
                                        但是其定义比较骇人
                         template
                                     template
                                     A&  A::operator=(const A& a)
                                   {  ...........................}



6.类模版的特化
      特化1个类模板(所有成员必须特化包括静态类数据成员(vc),但友元模板(1:1)可以
不特化,当作一个显示实参的函数模板处理即可) 或 特化1个模板 成员函数

         模板成员函数特化是定义必须出现在实现文件(cpp)中
       语法为
    void man::f(void)
{
............................
}
      
类特化
 template <>
class man
{
       ......//中所有类型参数以int 替代
};
      
  man::man()
{
......
}

void man::f(void)
{
}
注意  类成员中
   static const 有序类型可以在体内初始化static const int a=10;
                        仅仅static  必须在体外
                                                               static int a;
                                                              int woman::a=10;
   非 特化
   template
   int man::size=10;
   特化
   int man::size=10;
7偏特化
   类模板有1个以上模版参数(类型参数,非类型参数)
              某些模版参数 被实际的型和值取代(注意是 取代 ,不是增加,减少)
      如:

//////////////////头文件
       template
class wc
{
public:
 wc()
 {
  cout<<"\n int T1,T2, int";
 }
protected:
private:
};
template
class  wc
{
public:
 wc()
 {
  cout<<"\n in T *, T ,size";
 }
protected:
private:
};
template
class  wc
{
public:
 wc()
 {
  cout<<"\n in T* ,float,size";
 }
protected:
private:
};
template
class  wc
{
public:
 wc()
 {
  cout<<"\n in T* ,float,80";
 }
protected:
private:
};
///////头文件
//////main()
wc wc1;
 wc wc2;
 wc wc3;
wcwc4;
///////main() ,在vc 7 上通过
//////main()


8.预设模板参数(只有在类模板中才指定 ,1 .  明确指定 a   ,直接定义时 man<>  kkk;2. a )
template
class man
{
..........
}

写到这里突然想到
                  class A {
                            virtual void   print();
                              };
                  class B:public A {
                                          virtual void print();
                                          };
B b;
                 A *a =&b;
                a->print();//调用 B的,此时 print()中的this 指针是 B * const,使用B 的接口 ;

9.双重模板参数(很有用)
                template >
 class baby
 {
 public:
  baby ()
  {
   cout<<"\n in baby";
  }
 protected:
 private:
 };//类型参数可以是 类类型
        
baby > b;  //ok
////////////////////////
template class TT>//可以省略为 template   class  TT>
 class  son
 {
 public:
   TT * a; 
     son()
  {
           a=0;
   cout<<"\n in son";
  }
 protected:
 private:
 };
   son b;//则就含有了 man * a;
TT 是模板占位符号,是一个带1个类型参数的类模板,如果其有默认模板参数 则忽略掉  
所以 GG若带默认 的模板 应该如下
            template   > class GG>
class son
{
}

/////////   类模板类型参数 同时还可以是 类模板

10. 字符串常量在模板中的注意事项

           char * a="hi ,friend ";///"hi, friend"  文字常量 是 const char [10] 类型  左值转换到 const char *
限定转换到 char *,
                template       ostream& operator <<(ostream & os, const T & b);//注意只有const 才能接受临时变量

             cout<<"hi,friend";  
              cout<<"bad";
/////2个不同的模板实例
   typeid(变量).name();///直接打印出变量类型
写到这,闲扯下:
    栈区,堆区,全局(静态)区,文字常量,代码区,5个大区,这个是我听说的
////////////////////////////////////////////////
11.模板的编译模型
     在实例化点必须能找到定义//原则
                           只能使用包含模式了,
a..h. cpp 在 .h最后一行包含进 cpp
b. 全部在h 或 cpp

                     分离模式,目前支持的export 关键字i的编译器很少(vc.net 不支持)


12.
函数指针类型也能做模板类型参数

bool  minn( int  a, int  b)
{
      return  a < b;
 }

 template  < typename T1,typename T2 >
     const  T1 &   mymin( const  T1 &  t1,  const  T1 &  t2, T2 t3 )
  {
      return  t3(t1,t2) ? t1:t2;
 }
void  main()
{
cout << mymin( 2 , 3 ,minn);
}


13.
模板参数可以是个类模板  
template
class a
{
};
a< vector >;


template class con  >
void add(con,con)
{
 cout<<"ok";
}

add(a,b)//特殊在于 需要推导,vc 7 可以从  类模板中推导出参数类型

template class con >
class ggoo
{
public:
 con a;
con b;

protected:
private:
};

ggoo kk;//b, con 的模板参数可以任意