C++初学运算符重载和友元函数
C++运算符重载和友元函数
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
一、运算符重载
1.运算符重载的基本概念
1.1 运算符重载定义:C++ 允许在同一作用域中的某个函数和运算符指定多个定义。
运算符重载格式:
operatorop(argument-list);//op为运算符名称如+-*/等。
但是重载的运算符必须的有效的C++运算符,不能虚构一个新的符号,如不能有operator@()这样的函数。
1.2 重载限制
- 重载后的运算符必须只有有一个是用户定义的操作类型,这将防止用户为标准类型运算符进行重载。
- 使用运算符时不能违反原来的句法规则,且不能修改运算符优先级。
- 不能创建新运算符。
- 不能重载部分运算符。如sizeof, ., typeid等。
2.运算符重载的使用
示例代码如下:
class Time
{
private:
int hours;
int minutes;
public:
Time operator+(const Time & t) const;
Time operator-(const Time & t) const;
Time operator*(double n) const;
};
Time Time::operator+(const Time & t)const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes/60;
sum.minutes %= 60;
return sum;
}
Time Time::operator-(const Time & t) const
{
Time diff;
int tot1,tot2;
tot1 = t.minutes + 60 * t.hours;
tot2 = minutes + 60 * hours;
diff.minutes = (tot2 - tot1)/60;
return diff;
}
Time Time::operator*(double mult) const
{
Time result;
long totalminutes = hours * mult *60 + minutes * mult;
result.hours = totalminutes/60;
result.minutes = totalminutes % 60;
return result;
}
注意一下operator+()中的代码,参数为引用,返回类型却不是引用。 参数说明为引用是为了提高效率。然而返回值不能是引用,因为函数将创建一个新的Time对象(sum),来表示另外两个Time对象的和。 返回对象(如本代码所做的那样)将创建对象的副本,因此调用函数可以使用它。然而,如果返回类型为Time & ,则引用的将是sum对象,但由于sum对象是局部变量,在函数结束时将被删除,因此引用将指向一个不存在的对象。
不要返回指向局部变量或临时对象的引用。函数执行完成后,局部变量和临时对象将消失,引用将指向不存在的数据
二、友元函数
1.友元函数的基本概念
当我们使用operator重载运算符时,左侧的操作数应该是调用对象,这限制了该运算符的使用方式。所以为了解决这个问题我们可以引入友元函数。友元函数与类成员函数有相同的访问权限,故可以通过友元函数来访问私有对象。
1.1 创建友元
创建友元函数的第一步是将其原型放在类声明中,并在原型声明前加上关键字friend:
friend Time operator*(double m,const Time &t);
注意以下两点
-
虽然operator*()是在类声明中声明的,但是他不是成员函数,因此不能使用成员运算符调用;
-
虽然operator*()不是成员函数,但它的访问权限相同。
第二步是编写函数定义。因为它不是成员函数,所以不要使用Time::限定符。另外不要在定义中使用关键字friend. 函数定义如下:
Time operator*(double m,const Time & t)
{
Time result;
long totalminutes = t.hours * mult *60 + t.minutes * mult;
result.hours = totalminutes/60;
result.minutes = totalminutes % 60;
return result;0
}
总结
一般来说,访问私有类成员的唯一方法是使用类方法。C++使用友元函数来避开这种限制。要让函数成为友元,需要在类声明中声明该函数,并在声明前加上friend关键词。
|