首先引入一段代码
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
friend ostream &operator<<( ostream &output,
const Distance &D )
{
output << "F : " << D.feet << " I : " << D.inches;
return output;
}
friend istream &operator>>( istream &input, Distance &D )
{
input >> D.feet >> D.inches;
return input;
}
};
int main()
{
Distance D1(11, 10), D2(5, 11), D3;
cout << "Enter the value of object : " << endl;
cin >> D3;
cout << "First Distance : " << D1 << endl;
cout << "Second Distance :" << D2 << endl;
cout << "Third Distance :" << D3 << endl;
return 0;
}
声明一点:我们需要把输入输出运算符重载函数声明为类的友元函数,这样我们就能不用创建对象而直接调用函数。
对上面做句话做一个解释:如果在类中直接定义一个函数,比如在类中定义一个重载“+”的函数,那么在之后的调用时就需要先创建一个对象然后调用这个重载函数,比如在person类下定义了一个p1和一个p2对象,那么在之后的p1+p2操作时此处的p1就相当于创建的那个对象,对比输入输出流重载,因为输入输出流的使用对象只能是cout或者cin,所以咱们无法再创建别的输出输出流对象,而直接用编译器给的cout和cin。(结合下面对那行代码分析理解)
在上面代码的main函数中,详细分析下下面这行代码:
cout << "First Distance : " << D1 << endl;
此处执行 cout<<"First Distance:" 然后编译器会输出 First Distance: 同时会返回一个输出流(ostream)对象cout,这也就是为什么咱们可以一直输出下去的原因(因为一直会有一个输出流对象返回) 。然后执行 <<D1 ,这里完整的深入的写开实际上是:cout<<D1 然后会匹配到上面 的 << 重载函数
(为什么这里就会调用上面的重载呢,或者说为什么此处就是重载<<的调用时机呢?
原因是:此处<<两侧的类型和上面的重载函数形参列表中的类型匹配起来了,上面的形参有两个,一个是ostream类型一个是自定义的Distance类型,分别对应上面<<两侧的对象cout和D1。
注意:!!!!承接上文,因为cout是编译器给的,且不容变更,就是你不能再定义除cout外的别的输出流对象所以你必须把那重载函数写成友元的
)
然后根据重载函数中的规定输出完D1后又一个要强调的点来了,就是这个友元函数前面的返回值类型是ostream类型的引用!!而这种返回值有且只有一个叫做cout (是不是更理解一些了)写引用也是因为cout只有这一个的原因,cout<<D1执行结束后会返回cout,再执行<<endl(详细可以写为cout<<endl)实现换行操作
补充:假设,假设哈!不写那个friend 那么形参列表中的 osrteam & output就不用写了,直接下面调用时候就是一个对象设为p, p<<D1,而这个p他只能是cout,他不让咱们重给他起名字,所以这个p不能用,然后咱就给他写成友元,形参列表里面加一个&output 来代替p的作用。
希望大家可以看懂~,新手,笔法有些粗糙,然后可能表述不清楚大家见谅,可以评论区提问的~