左移运算符重载
作用:可以输出自定义数据类型
我们正常情况下无法输出自定义数据类型。这个时候就需要重载<<运算符
注意,通常不会用成员函数重载<<运算符,因为无法实现cout在左侧
成员函数只有一个参数
1.通常不会用成员函数重载左移运算符,首先如果这么写:void operator<<(Perosn &p),这是错误的,cout哪去了呢。
2.而void operator<<(cout),调用时(本质:p.operator<<(cout))会变成p<<cout,cout在右边,实际应该是cout<<P,cout在左边。
只能通过全局函数重载左移运算符
如何查找cout属于什么数据类型?点击cout,右键,选择转到定义
可以看到cout属于ostream类,也就是输出流对象
// 本质 operator<<(cout,p),简化cout<<p;
// cout传入的必须是引用,不能是值。因为全局只有一个cout,不能创造出一个新的cout出来。
// 如果函数返回的是void,我们只能使用一次cout<<。
// 如果返回的是cout,那么我们每执行一次cout<<,就返回cout,这样就可以无限追加内容了。
//上面的规则称为链式规则。
// 传入的是osream &cout,返回的也应该是引用
ostream &operator<<(ostream &cout,Person &p) {
cout << "p.m_A=" << p.m_A << " " << "p.m_B=" << p.m_B;
return cout;
}
// 也可写成下面这样,把cout改成其他名字。但是调用的时候还是cout<<p
// 因为引用就是起别名
/*
ostream& operator<<(ostream &b,Person &p) {
b << "p.m_A=" << p.m_A << " " << "p.m_B=" << p.m_B;
return b;
}
*/
重载运算符还可以和友元相结合
#include<iostream>
using namespace std;
#include<string>
// 左移运算符重载
// 作用:可以输出自定义数据类型
class Person {
// 友元,目的是让重载<<运算符的函数也可打印Person中的私有属性
friend ostream& operator<<(ostream& cout, Person& p);
friend void test01();
private:
int m_A;
int m_B;
// 通常不会用成员函数重载左移运算符,因为不需要p.operator<<(p);这是错误的
// 而void operator<<(cout),会变成p<<cout,cout在右边,实际应该是cout<<P,在左边
};
// 本质 operator<<(cout,p),简化cout<<p;
//链式规则,返回cout,可以无限追加
// 如何知道cout属于什么数据类型呢?点击cout,右键:转到定义(或者按F12)
ostream& operator<<(ostream &cout,Person &p) {
cout << "p.m_A=" << p.m_A << " " << "p.m_B=" << p.m_B;
return cout;
}
void test01() {
Person p;
p.m_A = 10;
p.m_B = 10;
cout << "这是普通输出:" << endl;
cout << "p.m_A=" << p.m_A << " " << "p.m_B=" << p.m_B << endl<<endl;
//链式规则,返回cout,可以无限追加
cout << endl << "链式规则:" << endl;
cout << p <<endl<<"hello,world"<<endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:1.重载左移运算符配合友元可以实现输出自定义数据类型
2.只能通过全局函数重载左移运算符
3.cout属于ostream类,并且重载函数必须传入的是cout的引用,返回的也必须是引用。→
ostream &(ostream &cout,Person p)。这样可以实现输出时无限追加内容。