11.1 运算符重载
C++中可以将运算符重载扩展到用户定义的类型,重载运算符格式
operator +() //重载+运算符
operator *() //重载*运算符
使用被重载的运算符对类对象进行操作的时候,会隐式调用运算符函数
11.2 运算符重载实例
首先是一个不带重载的Time 类实例,相加操作以成员函数来实现
head
#ifndef GOLF_H_INCLUDED
#define GOLF_H_INCLUDED
#include <cstring>
class Time
{
int m_hours;
int m_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;
void Show() const;
};
#endif // GOLF_H_INCLUDED
definition
// contain function called in file1
#include <iostream>
#include "golf.h"
Time::Time()
{
m_hours = m_minutes = 0;
}
Time::Time(int h, int m)
{
m_hours = h;
m_minutes = m;
}
void Time::AddMin(int m)
{
m_minutes += m;
m_hours += m_minutes / 60;
m_minutes %= 60;
}
void Time::AddHr(int h)
{
m_hours += h;
}
void Time::Reset(int h, int m)
{
m_hours = h;
m_minutes = m;
}
Time Time::Sum(const Time & t) const
{
Time sum;
sum.m_hours = m_hours + t.m_hours;
sum.m_minutes = m_minutes + t.m_minutes;
sum.m_hours += sum.m_minutes / 60;
sum.m_minutes %= 60;
return sum;
}
void Time::Show() const
{
std::cout << m_hours << " hours, " << m_minutes << " minutes\n";
}
main
#include <iostream>
#include "golf.h"
int main()
{
using std::cout;
using std::endl;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout << "planning time = ";
planning.Show();
cout << endl;
cout << "coding time = ";
coding.Show();
cout << endl;
cout << "fixing time = ";
fixing.Show();
cout << endl;
total = coding.Sum(fixing);
cout << "coding.sum(fixing) = ";
total.Show();
cout << endl;
return 0;
}
重载运算符就是将该运算符作为类的成员函数,将另一个类作为参数,使用的时候是隐式调用的,只需要直接用运算符就可以
重载加号就是把上面的sum变成operator()+
11.2.2 重载限制
- 重载的运算符也不必是成员函数,但必须至少有一个操作数是用户定义的类型,防止用户为标准类型重载运算符
- 不能违反原先的句法规则
- 不能创建新的运算符
- 不能重载以下运算符:sizeof, 成员运算符,作用域,条件三目运算符, typeid,const_cast, dynamic_cast, reinterpret_cast, static_cast。
- 只能选择成员函数方式重载的运算符:=, (), [ ], -> 。
注意:我刚刚想试试在类外重载运算符,结果编译提示我hour等变量是私有的,编译失败,所以我注意到,当我在类外重载时,类外的重载运算符函数中,使用hour等数据相当于是程序本身在直接使用其私有成员数据,所以是失败的。所以想要在类外重载,就要使用友元函数重载,以致可以使用私有成员
11.3 友元
关键字:friend
特性:可以使用所声明类中的成员函数的特权
11.3.2 常用友元,重载<<运算符
这种重载分两步:
//reference
friend std::ostream & operator<<(std::ostream & os, const Time & t);
//definition
std::ostream & operator<<(std::ostream & os, const Time & t)
{
os << t.m_hours << " hours " << t.m_minutes << " minutes" << std::endl;
return os;
}
friend关键字只在类中使用,类外不适用
11.6 类的自动转换和强制转换
自动转换是只有一个参数的构造函数特权,explicit关键字关闭自动类型转换,声明时加入此关键字即可
想要将用户定义 的类转换为标准类型,得用转换函数
创建转换函数
operator typeName();
注意:
- 转换函数必须是类方法
- 转换函数不能指定返回类型
- 转换函数不能有参数