模板类中重载<<和>>操作符

转:模板类中重载<<和>>操作符

模板类中操作符重载问题("<<"和">>"重载)

在模板类中输入流“>>”和输出流“<<”的重载,若使用友元在类内声明,在类外实现,那么连接时将会报错,但我们可以采用以下三种方式来实现输出流"<<"和"输入流>>"的重载。

一、将输出流"<<"和"输入流>>"重载的实现写在类中

复制代码
#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;
}
Set模板类是一种集合,它可以存储一组不同的元素,并且它们是按照某种规则排列的。可以通过重载+、-、<<>>操作符来实现Set模板类。在这里,我们需要定义一个模板类Set,这个类可以接受任意类型的元素作为其成员。 在定义Set类时,需要实现如下操作: 1. 实现一个构造函数,用于初始化Set对象; 2. 实现一个析构函数,用于销毁Set对象; 3. 重载+、-操作符,分别用于向Set对象中添加元素从Set对象中删除元素; 4. 重载<<>>操作符,分别用于输出输入Set对象中的元素。 下面是一个简单的Set类的代码示例: ```cpp #include <iostream> #include <set> using namespace std; template<typename T> class Set { public: Set() {} virtual ~Set() {} void add(const T& elem) { m_data.insert(elem); } void remove(const T& elem) { m_data.erase(elem); } friend Set operator+(const Set& s1, const Set& s2) { Set s = s1; for (auto it = s2.m_data.begin(); it != s2.m_data.end(); ++it) { s.add(*it); } return s; } friend Set operator-(const Set& s1, const Set& s2) { Set s = s1; for (auto it = s2.m_data.begin(); it != s2.m_data.end(); ++it) { s.remove(*it); } return s; } friend ostream& operator<<(ostream& os, const Set& s) { os << "{ "; for (auto it = s.m_data.begin(); it != s.m_data.end(); ++it) { os << *it << " "; } os << "}"; return os; } friend istream& operator>>(istream& is, Set& s) { T elem; while (is >> elem) { s.add(elem); } return is; } private: set<T> m_data; }; ``` 使用示例: ```cpp int main() { Set<int> s1, s2; s1.add(1); s1.add(2); s1.add(3); s2.add(2); s2.add(3); s2.add(4); Set<int> s3 = s1 + s2; // 并集 Set<int> s4 = s1 - s2; // 差集 cout << "s1: " << s1 << endl; cout << "s2: " << s2 << endl; cout << "s1 + s2: " << s3 << endl; cout << "s1 - s2: " << s4 << endl; cin >> s1; // 输入集合元素 cout << "s1: " << s1 << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值