C++ Primer Plus Chapter 11
Chapter11 使用类
运算符重载
函数重载是用同名函数完成相同的基本操作,甚至这种操作被用于不同的数据类型
-
运算符函数格式: operator op(argument-list),如operator+()。不能虚构新的运算符
-
district=sid+sara 编译器发现是操作数sara,是类对象,使用相应运算符函数替换上述运算符 district=sid.operator+(sara) ; 隐式使用sid,显式使用sara对象
-
不要返回指向局部变量或者临时对象的引用。函数执行后,局部变量和临时对象将消失,引用将指向不存的数据。例如:
Time & Time::Sum(const Time &T) const {Time sum; sum=T;return sum;}由于函数引用sum对象,sum对象为局部变量,函数结束删除,则最终指向不存在对象
Time & Time::Sum(const Time &T) const {Time sum; sum=T;return sum;} 由于函数有返回对象,将创建对象副本,调用函数可以使用
-
重载限制:
- 重载后的运算符必须至少有一个操作数是用户定义的类型,防止用户为标准类型重载运算符
- 使用运算符时不能违反运算符原来的句法规则。例如,不能将求模运算符(%)重载成+
- 不能创建新运算符
- 不能重载以下运算符:sizeof, .*, ::, ?:等
- 下列运算符智能通过成员函数进行重载:=:, ():, []:, ->
友元
友元: 友元函数,友元类,友元成员函数;关键字friend
友元函数:
-
将友元函数的原型放在类声明中,在声明前加上friend:friend Time operator*(double m, const Time & t);
-
operator *() 在类声明中声明的,但不是成员函数,不能使用成员运算符来调用,但是与成员函数的访问权限相同
常用友元:重载«运算符
-
«的第一种重载版本:
-
cout « trip; 使用友元函数,重载运算符
void operator« (ostream & os, const Time & t) { os « t.h « t.m; }
-
operator«()函数是Time类的友元函数,该函数不是ostream类的友元
-
-
«的第二种重载版本
trip为对象,实现cout « “Time” «trip;
ostream & operator«(ostream & os, const Time & t){os «t.hours «t.min; return os}
-
**只有在类声明中的原型才能使用friend关键字。除非函数定义也是原型,否则不能在函数定义中使用该关键字
-
重载运算符,用于成员函数或非成员函数(稍好)
重载:矢量类
-在Vector类中声明friend std::ostream & operator«(std::ostream & os, const Vector & v);
由于operator<<()是友元函数,而不在类作用域中,因此必须使用Vector::Rect,而不能使用RECT。由于这个友元函数在名称空间VECTOR中,无需使用全限定名VECTOR::Vector::RECT。
- 对已重载的运算符进行重载:使用的运算符数量与相应的内置C++运算符相同,就可多次重载同一个运算符
类的自动转换和强制类型转换
类的自动转换
- 任何接受唯一一个参数的构造函数都可被用作转换函数,将与该参数相同类型的值转为类;即将与该参数相同类型的值赋给对象,则自动调用构造函数
转换函数
-
要将类对象转换为其他类型,必须定义转换函数,支出如何进行这种转换;转换函数必须是成员函数
-
强制类型转换:将类类型转换为某种类型 operator typeName();
- 转换函数必须是成员函数
- 转换函数不能指定返回类型
- 转换函数不能有参数
- 必须返回转换后的值
Vector转换为double类型的函数: Vector::operator double(){ return a_doule_value; }
但是最好不要依赖于这种隐式转换函数 -
用功能相同的非转换函数替换该转换函数,但仅在被显式地调用,该函数才会被执行 Time::operator int(){ return int (hour+1);}替换为 int Time::Time_to_Int(){ return int (hour+1);}
则int plb=poppins为非法表示;int plb=popp.Time_to_Int();