操作符左右同类重载
重载举例:重载 + 实现两个符数的相加; 重载 << 流输出运算符 实现 cout<<c<<endl; 直接输出c的real&imagine。
(1)重载 + 部分,分别用友元和成员重载。体会两者不同
友元重载时,+函数定义在类声明之外,得传递两个参数c1,c2 使其相加。 operator+(c1,c2)
成员重载,+定义在类内的public部分作为成员函数,传递一个参数。使用时为:c1.operator+(c2)
(2)重载 << 部分,<< 为 ostream 类型
<< 重载的函数体起始很简单,也就是cout 内部实现的道理。重载<<之后的好处是不用再在类内定义dis函数来显示。直接用cout就可以输出私有数据。简单直观。
#include<iostream>
using namespace std;
class Complex
{
public:
Complex(int real = 0,int imagine = 0)
:_real(real),_imagine(imagine){}
void dis()
{
cout<<_real<<","<<_imagine<<endl;
}
// friend Complex operator + (Complex c1,Complex c2 ); + 友元重载
//成员重载
Complex operator + (Complex another)
{
this->_real += another._real;
this->_imagine += another._imagine;
}
//流运算符重载
friend ostream & operator << (ostream &os, Complex &c);
private:
int _real;
int _imagine;
};
/* + 友元重载
//使用时直接 c = c1 + c2;
Complex operator + (Complex c1,Complex c2 )
{
Complex c;
c._real = c1._real+c2._real;
c._imagine = c1._imagine + c2._imagine;
return c;
}
*/
//重载流运算符
ostream & operator << (ostream &os, Complex &c)
{
os<<c._real<<","<<c._imagine<<endl;
return os;
}
int main ()
{
Complex c1(1,3),c2(2,4);
Complex c3;
// c3 = c1 + c2; /*友元重载 + 运算符 使其可以用于复数的加法*/
c1.operator +(c2);//成员重载 +
c1.dis();
//重载流运算符 实现 cout<<c1<<endl; 即可输出c1的real&imagine
cout<<c1<<endl;
return 0;
}
操作符左右非同类重载
重载不仅可用于 运算符两边同类的还可以非同类。那么就涉及到 成员重载还是友元重载的问题。
如下示例:
Sender<<Mail1<<Mail2<<endl;
发送邮件 Sender 后跟收件地址,Mail 后为信件内容。Sender和Mail为两个不同的类。
此时:sender 为左操作数,决定了 operator << 为 Sender 的成员函数,而 mail 决定了operator<<要作 Mail 类的友员
//流输出运算符 重载
#include <iostream>
using namespace std;
class Mail;
class Sender
{
public:
Sender(string Addr)
:_Addr(Addr){}
Sender & operator << (class Mail &mail);
private:
string _Addr;
};
class Mail
{
public:
Mail(string time,string topic)
:_time(time),_topic(topic){}
friend Sender & Sender:: operator << (class Mail &mail);
private:
string _time;
string _topic;
};
Sender & Sender::operator << (class Mail &mail)
{
cout<<"Address to :"<<_Addr<<endl;
cout<<"Mail.time :"<<mail._time<<endl;
cout<<"Mail.topic :"<<mail._topic<<endl;
puts("");
return *this;
}
//Sender & Sender::operator << (string _Addr)
//{
// cout<<"Address to :"<<_Addr<<endl;
// cout<<"Mail.time :"<<Mail._time<<endl;
// cout<<"Mail.topic :"<<Mail._topic<<endl;
// return *this;
//}
int main()
{
Sender s1("jjjj@qq.com");
Mail mail1("2:00","jjjjj");
Mail mail2("4:00","mmmm");
s1<<mail1<<mail2;
Sender s3("mars@qq.com");
Mail mail3("4:00","chetui");
s3<<mail3;
return 0;
}
注意:
(1)Sender函数注释部分,第一次写的时候没有注意到 operator << 的左右操作数。
Sender << Mail 左边为Sender 类,则运算完的返回值类型为Sender 类型。右边为 Mail 类,则函数操作数为 Mail。
所以:函数声明应为
Sender & Sender:: operator << (class Mail &mail);
由此观之:Sender 为左操作数,所以 operator << 为Sender 的成员函数。而 Mail 决定了operator << 要做Mail 的成员。
(2)this指针的使用。
在函数体中,返回了this 指针 return *this;返回值类型为Sender 。this指向Sender定义的地址,保证了下一次使用同一地址的时候数据还可以找到。