第11章 使用类
- 如果函数使用常规参数而不是引用参数,将发生什么情况呢?
- 如果忽略了析构函数,又将发生什么情况呢?
- 运算符重载,它允许将标准
C++
运算符用于类对象。 - 友元,这种
C++
机制使得非成员函数可以访问私有数据。 - 介绍如何命令
C++
对类执行自动类型转换。
11.1 运算符重载
- 运算符重载是一种形式的
C++
多态。 - 要重载运算符,需使用被称为运算符函数的特殊函数形式。
运算符函数格式如下:
operatorop(argument-list)
op
必须是有效的C++
运算符,不能虚构一个新的符号。
11.2 计算时间:一个运算符重载示例
注意参数是引用,但返回类型却不是引用。
将参数声明为引用的目的是为了提高效率。
警告
不要返回指向局部变量或临时对象的引用。函数执行完毕后,局部变量和临时对象将消失,引用将指向不存在的数据。
11.2.1 添加加法运算符
11.2.2 重载限制
C++
对用户定义的运算符重载的限制:
- 重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符。
- 使用运算符时不能违反运算符原来的句法规则。
– 不能修改运算符的优先级。 - 不能创建新运算符。
- 不能重载下面的运算符。
- 下表中的大多数运算符都可以通过成员或非成员函数进行重载。
下面的运算符只能通过成员函数进行重载。
=
:赋值运算符()
:函数调用运算符[]
:下标运算符->
:通过指针访问类成员的运算符
11.2.3 其他重载运算符
11.3 友元
C++
控制对类对象私有部分的访问,公有类方法提供唯一的访问途径,但有时这种限制太严格。
C++
提供了另外一种形式的访问权限:友元。
- 友元函数:通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限。可以访问类的私有成员。
- 友元类(第15章介绍)
- 友元成员函数(第15章介绍)
11.3.1 创建友元
创建友元函数的第一步是将其原型放在类声明中,并在原型声明前加上关键字friend;
第二步是编写函数定义。
- 虽然友元函数在类声明中声明的,但它不是成员函数,因此不能使用成员运算符来调用。
- 虽然友元函数不是成员函数,但它与成员函数的访问权限相同。
友元是否有悖于OOP
- 应将友元函数看作类的扩展接口的组成部分。
- 类声明仍然控制了那些函数可以访问私有数据。
提示:
如果要为类重载运算符,并将非类的项作为其第一个操作数,则可以用友元函数来反转操作数的顺序。
11.3.2 常用的友元:重载<<运算符
1. <<的第一种重载版本
函数成为Time类的一个友元函数。
2. <<的第二种重载版本
代码:mytime0.h
#include <iostream>
class Time{
private:
int hours;
int minutes;
public:
Time();
Time(int h,int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h=0,int m=0);
Time Sum(const Time & t) const;
Time operator+(const Time & t) const;
Time operator-(const Time & t) const;
Time operator*(double mult) const;
void Show() const;
friend Time operator*(double m, const Time & t){
return t*m;
};
friend std::ostream & operator<<(std::ostream & os, const Time & t);
};
代码:mytime0.cpp
#include <iostream>
#include "mytime0.h"
Time::Time(){
hours = minutes = 0;
}
Time::Time(int h,int m){
hours = h;
minutes = m;
}
void Time::AddMin(int m){
minutes += m;
hours += minutes/60;
minutes = minutes%60;
}
void Time::AddHr(int h){
hours += h;
}
void Time:: Reset(int h,int m){
hours = h;
minutes = m;
}
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;
}
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