左移运算符重载
#include<bits/stdc++.h>
using namespace std;
class Person
{friend ostream & operator<<(ostream &cout,Person &p);
public:Person(int a,int b){m_A = a;m_B = b;}
private://利用成员函数重载 左移运算符 //p.operaor<<(cout) 简化版本p<<cout//不会利用成员函数重载<<运算符,因为无法实现cout在左侧//void operaor<<(cout)//{ } int m_A;int m_B;};
ostream & operator<<(ostream &cout,Person &p)//本质为 operator<<(cout,p) 简化 cout<<p 
{cout<<"m_A= "<<p.m_A<<" m_B= "<<p.m_B;
}
void test01()
{Person p(10,20);cout<<p<<endl; 
}
int main(){test01();return 0;
}
为什么重载
<<运算符时需要返回ostream&类型的引用呢?
1. 链式调用
返回 ostream& 类型的引用允许我们实现链式调用,例如:
cout << p1 << p2 << p3;
这种语法会被编译器解释为:
(((cout << p1) << p2) << p3);
每次 << 运算符重载函数返回的都是 cout 对象的引用,这样才能够连续地将多个对象输出到同一个 cout 流中。
2. 流式输出
C++ 中的 << 运算符经常用于实现流式输出的效果,例如 cout << "Hello" << " " << "World" << endl;。每个 << 运算符都将数据追加到 cout 流中,因此 << 运算符的返回类型必须是 ostream&,以确保可以继续将数据输出到同一个流中。
3. 返回类型为什么是引用
返回引用而不是值的另一个原因是为了避免不必要的对象复制。如果每次 << 运算符返回的是 ostream 对象而不是引用,那么在每次函数调用结束时会产生一个临时的 ostream 对象副本,这不仅效率低下,而且破坏了期望的输出顺序。
因此,返回 ostream& 类型的引用是为了支持链式调用和流式输出的正确性和效率。这也是 C++ 中惯例和推荐的做法。
为什么要将 m_A 和 m_B 私有化?
-  封装性和安全性: 将数据成员声明为私有的意味着它们只能被 Person类的成员函数访问,而外部代码不能直接访问或修改这些成员。这样做提高了类的封装性,避免了数据被不相关的代码误用或修改。
-  数据访问控制: 通过公开的构造函数 Person(int a, int b),类的使用者可以在创建对象时初始化m_A和m_B,而后续的访问和修改必须通过类的公有接口或者友元函数来进行,从而保证了数据的安全性和一致性。
-  友元函数访问: 尽管 m_A和m_B是私有的,但operator<<被声明为Person类的友元函数,可以访问Person对象的私有成员。这样做既保留了数据的封装性,又允许特定函数或类进行必要的数据操作,例如输出Person对象的信息。