轉:模板類中重載操作符


模板類中操作符重載問題("<<"和">>"重載)

在模板類中輸入流“>>”和輸出流“<<”的重載,若使用友元在類內聲明,在類外實現,那麼連接時將會報錯,但我們可以採用以下三種方式來實現輸出流"<<"和"輸入流>>"的重載。

一、將輸出流"<<"和"輸入流>>"重載的實現寫在類中

複製代碼
#include "stdafx.h"
#include   <iostream>
using   namespace   std;  
   
template<class T>  
class Test  
{  
   public:  
      Test(const T& t):data(t){}
      //---------------------------------------------
      friend ostream& operator<<(ostream& out,Test<T>& t)    //輸出流重載聲明及實現
      {
           return out<<"data   is   "<<t.data;
      } //--------------------------------------------
      friend istream& operator>>(istream& in,Test<T>& t)      //輸入流重載聲明及實現
      {
          return in>>t.data;
      }//---------------------------------------------
   private:  
      T data;  
};//-----------------------------------------------------------------      
      
int   main()  
{  
   Test<int> b(3);  
   cout<<b<<'\n';  
   cin>>b;
   cout<<b<<'\n';
   return 0;
}
複製代碼

那麼輸入輸出流重載爲什麼不能在類內聲明,類外實現呢??因爲模板比較特殊,若果在模板類外實現重載的話:

template<class T>
ostream& operator<<(ostream& out,Test<T>& t)
{
        return out<<"data   is   "<<t.data;
//--------------------------------------------

上面正好是函數模板的定義,而我們知道操作符重載函數不是類的成員函數,因此此處相當於定義了一個新的函數模板(不同於類中的friend ostream& operator<<(ostream& out,Test<T>& t) )。但若去掉template<class T> ,函數中的參數Test<T>就不知是什麼類型,所以不能在模板類內聲明,類外實現操作符重載。

二、既然類外實現相當於重定義了一個函數模板,那麼只要他不使用類的私用成員即可,因此重載的函數模板只有通過類的公有成員函數來實現對類的私有成員的操作,這樣不必在類內聲明它爲友元,直接在類外重載即可。

複製代碼
#include "stdafx.h"
#include   <iostream>
using   namespace   std;  
   
template<class T>  
class Test  
{  
   public:  
      Test(const T& t):data(t){}
      T GetData()const{return data;}
      void SetData(T &item){data=item;}
   private:  
      T data;  
};//-----------------------------------------------------------------
template<class T>      
ostream& operator<<(ostream& out,Test<T>& t)   
{
      return out<<"data   is   "<<t.GetData();
//--------------------------------------------
template<class T>
istream& operator>>(istream& in,Test<T>& t)     
{
     T item;
    in>>item;
    t.SetData(item);
    return in;
}//---------------------------------------------      
int   main()  
{  
   Test<int> b(3);  
   cout<<b<<'\n';  
   cin>>b;
   cout<<b<<'\n';
   return 0;
複製代碼

三、使用過渡函數


複製代碼
#include "stdafx.h"
#include   <iostream>
using   namespace   std;  
   
template<class   T>  
class   Test  
{  
   public:  
      Test(const T& t):data(t){}
      //---------------------------------------------
      template<class CharT,class CharTraits>  
      basic_ostream<CharT,CharTraits>& Output(basic_ostream<CharT,CharTraits>& out)const    //輸出流過渡函數
      {
            return out<<"data   is   "<<data;
      } //--------------------------------------------
      template<class   CharT,class   CharTraits>  
      basic_istream<CharT,CharTraits>& Input(basic_istream<CharT,CharTraits>& in)    //輸入流過渡函數
      {
          return in>>data;
      }//---------------------------------------------
   private:  
      T data;  
};//-----------------------------------------------------------------      
template<class T,class CharT,class CharTraits>  
basic_ostream<CharT,CharTraits>& operator<<(basic_ostream<CharT,CharTraits>& out,const Test<T>& t)   //輸出流重載
{  
    return t.Output(out);  
}//------------------------------------------------------------------      
template<class T,class CharT,class CharTraits>  
basic_istream<CharT,CharTraits>& operator>>(basic_istream<CharT,CharTraits>& in,Test<T>& t)   //輸入流重載
{  
    return t.Input(in);  
}//------------------------------------------------------------------      
int   main()  
{  
   Test<int>   b(4);  
   cout<<b<<'\n';  
   cin>>b;
   cout<<b<<'\n';
   return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章