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();