示例解释重载
假设trip是一个Time对象。为显示Time的值,可以使用show()函数,然而,如果可以像下面这样操作更好:
cout<< trip; //make cout recognize Time class?
解释
<< 是可以被重载的C++运算符之一。
cout是一个 ostream 对象,它是智能的,能够识别所有的c++ 基本类型。这是因为对于每种基本类型,ostream 类声明中都包含了相应的重载的operator<<() 定义。
因此,要使cout 能够识别Time对象,一种方法是将一个新的函数运算符添加到 ostream 类的声明中。
但修改 iostream 文件不安全,这样做会在标准接口上浪费时间。相反,通过Time 类声明来让 Time 类知道如何使用cout 。
<<的第一种版本
要使Time 类对象知道使用 cout ,必须使用友元函数。这是什么原因呢?因为下面这样的语句使用两个对象,第一个是 ostream类对象(cout) :
cout << trip;
如果使用一个Time成员函数来重载<<,Time对象将是第一个操作数,就像使用成员函数重载 * 运算符那样。这意味着必须这样使用:
trip << cout ;// if operator<<() were a Time member function
这样会令人迷惑。但通过使用友元函数,可以像下面这样重载运算符:
void operator<<(ostream &os , const Time &t){
os << t.hours <<"hours, "<< t.minutes << "minutes" ;
}
这样可以使用下面的语句:
cout << trip;
打印结果:
4 hours,23 minutes
<<的第二种版本
前面介绍的实现存在一个问题,像下面这样的语句可以正常工作:
cout << trip ;
但这种实现不允许像通常那样将重新定义的 << 运算符与cout 一起使用:
cout << "Trip time: "<< trip <<" (Tuesdays)\n"; //can't do
小知识点
以上不可行原因
int x = 5;
int y = 8;
cout << x << y;
// cout 从做到右输出语句,意味着它等同于:(cout << x) << y;
正如 iostream 中定义的那样 ,<< 运算符左边必须是一个 ostream 对象。
ostream 类将 operator<<() 函数实现为返回一个指向 ostream 对象的引用。具体的说,它返回一个指向调用对象(这里是cout)的引用。
因此,表达式(cout << x)本身就是 ostream对象cout ,从而可以位于 << 运算符的右侧 。
可以对友元函数采用相同的方法。只要修改 operator<<() 函数, 让它返回 ostream 对象的引用即可:
ostream & operator<<(ostream & os , const Time &t)
{
os << t.hours << " hours, " << t.minutes << "minutes";
return os;
}
本文详细介绍了如何使用C++中的友元函数重载输出操作符<<,以便能够方便地显示自定义类如Time的值。通过示例解释了两种不同的重载方法,包括为什么需要使用友元函数以及如何处理运算符链式调用的问题。
&spm=1001.2101.3001.5002&articleId=106749560&d=1&t=3&u=d8d57346ee5a4ea386bf6e0938049482)
1582

被折叠的 条评论
为什么被折叠?



