C++拷贝构造函数和运算符重载--4 https://developer.aliyun.com/article/1424601
首先我们先观察以下代码:
#include<iostream> using namespace std; class Date { public: void operator<<(ostream& out) { out << _year << "/" << _month << "/" << _day << endl; } void operator>>(istream& in) { in >> _year >> _month >> _day; } private: int _year = 2023; int _month = 10; int _day = 16; }; int main() { Date d1; //cin >> d1;// 相当于cin.operator>>(d1);系统报错 d1 >> cin;// 相当于d1.operator<<(cin);正常运行 //cout << d1;// 相当于cout.operator<<(d1);系统报错 d1 << cout;// 相当于d1.operator<<(cout);正常运行 return 0; }
因为双操作数的运算符第一个参数是左操作数,第二个参数是右操作数,而在Date对象内部中,Date类对象默认占第一个位置,导致了以上情况的发生。
要想解决以上的问题,保证代码的可读性,就改变参数的位置,显然这不能在类对象的内部定义,必须在外部定义。
无返回类型的使用(即不支持连续使用)
#include<iostream> using namespace std; class Date { public: int _year = 2023; int _month = 10; int _day = 16; }; void operator<<(ostream& out, const Date& d) { out << d._year << "/" << d._month << "/" << d._day << endl; } void operator>>(istream& in, Date& d) { in >> d._year >> d._month >> d._day; } int main() { Date d1; cin >> d1;// 相当于cin.operator>>(d1);正常运行 cout << d1;// 相当于cout.operator<<(d1);正常运行 return 0; }
运用图解
有返回类型的使用(即支持连续使用)
#include<iostream> using namespace std; class Date { public: int _year = 2023; int _month = 10; int _day = 16; }; ostream& operator<<(ostream& out, const Date& d) { out << d._year << "/" << d._month << "/" << d._day << endl; return out; } istream& operator>>(istream& in, Date& d) { in >> d._year >> d._month >> d._day; return in; } int main() { Date d1, d2; cin >> d1 >> d2;// 从左到右连续进行,返回类型为输入流类的引用 cout << d1 << endl << d2;// 从左到右连续进行,返回类型为输出流类的引用 return 0; }
这里要注意几个问题:
1,当在外部定义时,因为是在外面访问成员对象的,因此权限必须设为public。
2,在使用 “ >> ” 运算符时,因为是要对成员对象进行输入流给值的操作,所以类对象不能加用const。
3,连续使用运算符操作相当于连续不断的赋值操作,这里需注意函数的返回类型。
总结一下:除流操作符以外的操作符一般是实现成员函数,“ >>,<< ”流运算要在外部实现,只有这样才能让流对象做第一个参数,实现可读性。还有就是要注意函数的返回类型,因为有了返回类型,才能实现连续使用运算符的操作。