重点:常用于定义两个类之间的运算,比如重载+运算符,实现两个类相加等。目的是隐藏内部机理,强调了实质。
例如通过运算符重载实现两个Time类的相加,函数声明为:
Time Operator+(const Time & t) const;
定义函数头为:
Time Time::operator+(const Time & t) const
把operator+看作成员函数名,可以用函数表示法如下调用:
total = a.operator+(b);
可以使用运算符表示法,更为直观:
total = a + b;
需要注意,在运算符表示法中,运算符左侧的对象是调用对象,右边的对象是作为参数被传递的对象。
由于+是从左向右结合的运算符,还能这么用:
total = a + b + c;
其相当于:
total = a.operator+(b.operator+(c));
运算符重载的限制:
重载后的运算符必需至少有一个操作数是用户定义的类型,可以防止用户为标准类型重载与运算符;不能违反运算符原来的句法规则;不能修改运算符优先级;不能创建新的运算符。
友元:公有类提供唯一访问私有成员数据的途径,但这种限制太严格。于是C++提供了友元机制,包括:
友元函数;友元类;友元成员函数。
友元函数即赋予该函数与类的成员函数相同的访问权限。
重载二元运算符时常常需要友元,能避免左边的操作数必须是类对象的限制,例如数乘。采用非成员函数重载运算符,左边的操作数对应于第一个参数,右边的操作数对应于第二个参数,同时又能因为友元函数而访问类的私有成员。
A = 2.75 * B;
相当于调用:
A = operator*(2.75,B);
其原型:
friend Time operator*(double m, const Time & t);//虽在类声明中声明,但不是成员函数,然而却与成员函数访问权限相同。另外由于不是成员函数,在类实现定义文件cpp中不要使用Time::等限定符,且不要使用friend。
友元并不违背面向对象,类声明仍然控制了哪些函数可以访问私有数据,应将友元函数看作类的扩展接口的组成部分,类方法和友元只是表达类接口的两种不同机制。
另外,友元在重载<<运算符中也起重要作用。想用cout<<trip;直观地实现输出,如果采用成员函数重载运算符,则左边的操作数必须是Time类对象,只能这么用:trip<<cout;太不直观。因此使用友元,同时返回ostream对象的引用可以继承连续<<输出的特点。
std::ostream & operator<<(std::ostream & os, const Time & t)
{
os << ..;
return os;
}
记得声明的原型中要加friend关键字。
非成员版本的重载运算符函数所需的形参数目与运算符使用的操作数数目相同,而成员函数版本所需的参数数目少一个,因为其中的一个操作数是被隐式地传递的调用对象。
新闻热点
疑难解答
图片精选