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

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

 #include  <iostream>
using std::cout;
using std::cin;
using  std::endl; 
   
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  <iostream>
using  std::cout;
using std::cin;
using std::endl;
   
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  <iostream>
using  std::cout;
using std::cin;
using std::endl;
   
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,classCharTraits>  
basic_ostream<CharT,CharTraits>&operator<<(basic_ostream<CharT,CharTraits>& out,constTest<T>& t)   //输出流重载
{  
   return t.Output(out);  
}//------------------------------------------------------------------      
template<class T,class CharT,classCharTraits>  
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;
}


好的,以下是一个简单的实现示例: ```c++ #include <iostream> #include <set> template<typename T> class Set { private: std::set<T> m_set; public: Set() {} Set(std::initializer_list<T> list) : m_set(list) {} void insert(const T& value) { m_set.insert(value); } void remove(const T& value) { m_set.erase(value); } friend Set operator+(const Set& set1, const Set& set2) { Set result; for (const auto& value : set1.m_set) result.insert(value); for (const auto& value : set2.m_set) result.insert(value); return result; } friend Set operator-(const Set& set1, const Set& set2) { Set result; for (const auto& value : set1.m_set) if (!set2.m_set.count(value)) result.insert(value); return result; } friend std::ostream& operator<<(std::ostream& os, const Set& set) { os << "{ "; for (const auto& value : set.m_set) os << value << " "; os << "}"; return os; } friend std::istream& operator>>(std::istream& is, Set& set) { T value; is >> value; set.insert(value); return is; } }; int main() { Set<int> set1 = { 1, 2, 3 }; Set<int> set2 = { 2, 3, 4 }; std::cout << "set1 = " << set1 << std::endl; std::cout << "set2 = " << set2 << std::endl; Set<int> set3 = set1 + set2; std::cout << "set1 + set2 = " << set3 << std::endl; Set<int> set4 = set1 - set2; std::cout << "set1 - set2 = " << set4 << std::endl; std::cout << "Enter a value to insert into set1: "; std::cin >> set1; std::cout << "set1 = " << set1 << std::endl; return 0; } ``` 以上代码定义了一个 `Set` 类,其 `m_set` 是一个 `std::set` 对象,实现了两个成员函数 `insert` 和 `remove` 来插入和删除元素,以及 `operator+` 和 `operator-` 重载运算符实现集合的并集和差集,`operator<<` 和 `operator>>` 重载运算符用于输出和输入集合。在 `main` 函数,我们创建了两个 `Set` 对象 `set1` 和 `set2`,并演示了如何使用重载的运算符进行集合操作,以及如何使用 `operator>>` 向 `set1` 插入元素。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值