《C++ Primer Plus》第11章知识点总结
运算重载符
C++允许将运算符重载扩展到用户定义的类型,例如,允许使用+将两个对象相加。编译器将根据操作数的数目和类型决定使用哪种加法定义。格式如下:
operatorop(argument-list)
例如,operator+()重载+运算符,operator*()重载*运算符。这里op必须是有效的C++运算符,不能虚构一个新的符号,例如operator@()。
请看下面两个例子,两段代码等价
//类中的声明
Time Sum(const Time& t)const;
...
//方法实现的细节
Time Time::Sum(const Time& t)const
{
Time sum;
sum.minutes=minutes+t.minutes;
sum.hours=hours+t.hours+sum.minutes/60;
sum.minutes%=60;
return sum;
}
...
//main函数中的调用
total=coding.Sum(fixing);
//类中的声明
Time operator+(const Time& t)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;
}
...
//main函数中的调用
total=coding+fixing;
有很多条,看书P387或上网查
友元
通过让函数称为类的友元,可以赋予该函数与类的成员函数相同的访问权限
友元有3种
(1)友元函数
(2)友元类
(3)友元成员函数
左侧的操作数时调用对象,例如A=B*2.75;这条语句可以被转化为A=B.operator*(2.75);但是A=2.75*B;这语句的左侧操作数——2.75不是对象。因此,编译器不能使用成员函数来替换表达式。解决方法是使用非成员函数。非成员函数不是对象调用的,它使用的所有值(包括对象)都是显式参数。因此使用非成员函数可以按所需的顺序获得操作数。但引发了一个新问题:非成员函数不能直接访问类的私有数据,至少常规非成员函数不能访问。然而,有一类特殊的非成员函数可以访问类的私有成员,它们被称为友元函数。
创建友元
第一步:将其原型放在类声明中,并在原型声明前加上关键字friend:
friend Time operator*(double m,const Time& t);
该原型意味着下面亮点;
(1)虽然operator*()函数是在类声明中声明的,但它不是成员函数,因此不能使用成员运算符来调用
(2)虽然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;
}
有了上述声明和定义后,下面的语句:
A=2.75*B;
将转换为如下语句,从而调用刚才定义的非成员友元函数:
A=operator*(2.75,B);
转换函数
转换函数时用户定义的强制类型转化,可以像使用强制类型转换那样使用它们。
要转换为typeName类型,需要使用这种形式的转换函数:operator typeName();
请注意以下几点:
(1)转换函数必须是类方法
(2)转换函数不能指定返回类型
(3)转换函数不能有参数
//类中的原型声明
operator int();
...
//方法实现的细节
Stonewt::operator int() const
{
return int (pounds+0.5);
}
...
//main函数中的调用
cout<<int(popins)<<endl;
C++为类提供了下面的类型转换
(1)只有一个参数的类构造函数用于将参数与该参数相同的值转换为类类型。例如,将int值赋给Stonewt对象时,接受int参数的Stonewt类构造函数将自动被调用。然而,在构造声明中使用explicit防止隐式转换,而只允许显式转换
(2)被称为转换函数的特殊类成员运算符函数,用于将类对象转换为其他类型。转换函数是类成员,没有返回类型、没有参数、名为operator typeName(),其中typename,typeName是对象被转换成的类型。将类对象赋给typeName变量或将其强制转换为typeName类型时,该转换函数将自动被调用。