1.简单的操作符重载范例
要重载操作符,需使用被称为操作符函数的特殊函数形式。操作符函数格式如下:
operator op(argument-list)
2.C++对操作符重载的限制
1)重载后的操作符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载操作符。
2)使用操作符时不能违反操作符原来的句法规则,如:不能将(%)重载成使用一个操作数。同样,不能修改操作符的优先级。
3)不能定义新的操作符。
4)不能重载下面的操作符以及可被重载的操作符:
https://p-blog.csdn.net/images/p_blog_csdn_net/xuanya0214/EntryImages/20091008/1.jpg
5)大多数操作符都可以通过成员或非成员函数进行重载,但下面的操作符只能通过成员函数进行重载。
https://p-blog.csdn.net/images/p_blog_csdn_net/xuanya0214/EntryImages/20091008/2.jpg
3.用友元函数来重载操作符
初衷:在上面的程序中,从概念上说B*2.75和2.75*B相同,但后一个表达式不对应于成员函数,因为2.75不是Time类型的对象。
友元函数原型声明前要加关键字friend。但是定义中不要用friend,也不要使用Time::限定符。上面程序的*重载可以写成以下形式:
https://p-blog.csdn.net/images/p_blog_csdn_net/xuanya0214/EntryImages/20091008/3.jpg
4.重载<<操作符
必须用友元函数。因为trip<<cout;这样将令人迷惑。
修改后的Time程序:
5.重载操作符作为成员函数还是非成员函数
非成员函数应是友元函数,这样它才能直接访问类的私有数据。非成员版本的重载操作符函数所需的形参数目与操作符使用的操作符数目相同,而成员版本所需的参数数目少一个,因为其中的一个操作数是被隐式地传递的调用对象。定义操作符时,必须选择其中一种,而不能同时选择。那么哪种格式最好呢?对于某些操作符来说,成员函数是唯一合法的选择,其他情况下,这两种格式没有太大的区别。有时根据类设计,使用非成员版本可能更好(尤其是为类定义类型转换时)。
6.一个矢量类
注意例子中名字空间的应用
7.类的自动转换和强制类型转换
某种类型到类类型的转换:
接受一个参数的构造函数为将类型与该参数相同的值转换为类提供了蓝图。
如果有下面的构造函数:Stonewt(double lbs);则可编写这样的代码: Stonewt myCat; myCat=19.6; 程序用构造函数Stonewt(double)来创建一个临时的Stonewt对象,并将19.6作为初始化值。随后,采用逐成员赋值方法将该临时对象的内容复制到myCat中。这一过程称为隐式转换,因为它是自动进行的,不需要显式强制类型转换。只有接受一个参数的构造函数才能作为转换函数。不过,有时候会导致意外的类型转换,C++可以用关键字explicit来关闭这种自动特性。如:explicit Stonewt(double lbs);关闭上述介绍的隐式转换,仍然允许显式强制类型转换:Stonewt myCat; myCat=Stonewt(19.6);myCat=(Stonewt)19.6;
还有一点,函数原型化提供的参数匹配过程,允许使用Stonewt(double)构造函数来转换其他数值类型。比如Stonewt myCat(7000);首先将int转换为double,然后才使用构造函数。但是,当且仅当转换不存在二义性时,才会进行这种二步转换。比如如果还定义了Stonewt(long),则编译器将拒绝这些语句,因为不知道将int转换为double还是long。
再比如有函数void display(const Stonewt & st, int n);而有下面调用代码display(422,2);display()原型表明第一个参数应为Stonewt对象。遇到int参数时,编译器查找Stonewt(int)构造函数,以便将该int转换为Stonewt类型。由于没有找到这样的构造函数,因此编译器寻找接受其他内置类型(int可以转换为这种类型)的构造函数。Stonewt(double)构造函数满足这种要求,因此编译器将int转换为double,然后使用Stonewt(double)将其转换为一个Stonewt对象。
类类型到某种类型的转换(转换函数):
如何创建转换函数呢?要转换为typeName类型,需要使用这种形式: operator typeName(); 要注意以下几点:转换函数必须是类方法;转换函数不能指定返回类型;转换函数不能有参数。
如果只是cout<<poppins,由于存在二义性,不知道转换为int还是double。但仍可以用强制类型转换,如long gone=(double)poppins;long gone2=int (poppins);原则上说,最好使用显式转换,而避免隐式转换。explicit不能用于转换函数,但只需要一个功能相同的非转换函数替换该转换函数即可,但仅在被显式地调用时,该函数才会执行。也就是说,可以将:Stonewt::operator int()替换为: int Stonewt::Stonewt_to_Int()。这样,下面语句将是非法的:int plb=poppins;但如果实在需要这种转换,可以这样做:int plb=poppins.Stonewt_to_Int();。
8.在main()之前调用Bootstrap函数
https://p-blog.csdn.net/images/p_blog_csdn_net/xuanya0214/EntryImages/20091008/4.jpg