1、
重载操作符必须具有至少一个类类型或枚举类型的操作数。这条规则强制重载操作符不能重新定义用于内置类型对象的操作符含义。
2、作为类成员的重载函数,其形参看起来比操作数数目少1。 作为成员函数的操作符有一个隐含的this形参,限定为第一个操作数。
3、一般将算术和关系操作符定义为非成员函数,而将赋值操作符定义为成员。当操作符为成员函数,this指向左操作数。 操作符定义为非成员函数时,通常必须将它们设置为所操作类的友元。
4、重载逗号、取地址、逻辑与、逻辑或等操作符通常不是好做法。这些操作符具有有用的内置含义,如果women定义了自己的版本,就不能再使用这些内置含义。
当一个重载操作符的含义不明显时,给操作取一个名字更好。对于很少用的操作,使用命名函数通常也比用操作符更好,如果不是普通操作,没有必要为简洁而使用操作符。
5、下面是一些指导原则, 有助于决定将操作符设置为类成员还是普通非成员函数
① 赋值( =)、下标( [])、调用( ())和成员访问箭头( ->)等操作符必须定义为成员,将这些操作符定义为非成员函数将在编译时标记为错误。
② 像赋值一样,复合赋值操作符通常应定义为类的成员。与赋值不同的是,不一定非得这样做,如果定义非成员复合赋值操作符,不会出现编译错误。
③ 改变对象状态或与给定类型紧密联系的其他一些操作符,如自增、自减和解引用,通常应定义为类成员。
④ 对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通的非成员函数。
6、 输出操作符<<的重载:为了与IO标准库一致,操作符应接受ostream&作为第一个形参,对类类型const对象的引用作为第二个形参,并返回对ostream形参的引用。 一般而言,输出操作符应输出对象的内容,进行最小限度的格式化,它们不应该输出换行符。
我们不能将该操作符定义为类的成员,否则,左操作数将只能是该类类型的对象。
//if operator<< is a member of Sales_item
Sales_item item;
item<<cout;
7、 输入操作符>>的重载:与输出操作符类似,输入操作符的第一个形参是一个引用,指向它要读的流,并且返回的也是对同一个流的引用。它的第二个形参是对要读入的对象的非const引用,该形参必须为非const,因为输入操作符的目的是将数据读入这个对象中。
8、 为了与内置操作符保持一致,加法返回一个右值,而不是一个引用。 既定义了算术操作符又定义了相关复合赋值操作符的类,一般应使用复合赋值实现算术操作符。 定义了operator==的类更容易与标准库一起使用,有些算法,如find,默认使用==操作符,如果类定义了==,则这些算法可以无须任何特殊处理而用于该类类型。
9、关联容器以及某些算法,使用默认<操作符,一般而言,关系操作符,诸如相等操作符,应定义为非成员函数。
10、赋值操作符可以重载,无论形参为何种类型,赋值操作符必须定义为成员函数,这一点与复合赋值操作符有所不同。 一般而言,赋值操作符与复合赋值操作符应返回左操作数的引用。
11、类定义下标操作符时,一般需要定义两个版本: 一个为非const成员并返回引用, 另一个为const成员并返回const引用。 箭头操作符必须定义为类成员函数。 解引用操作符不要求定义为成员,但将它作为成员一般也是正确的。
12、为了与内置类型一致,前缀式操作符应返回被增量或减量对象的引用。 为了区别操作符的前缀和后缀形式,
后缀式操作符函数接受一个额外的int型形参,使用后缀操作符时,编译器提供0作为这个形参的实参。
为了与内置操作符一致,后缀式操作符应返回旧值。并且,应作为值返回,而不是返回引用。
如果想要使用函数调用来调用后缀式操作符,必须给出一个整型实参值。
例: parr.operator++(0);//call postfix operator++
parr.operator++(); //call prefix operator++
13、函数调用操作符必须声明为成员函数。一个类可以定义函数调用操作符的多个版本,由形参的数目或类型加以区别。 定义了调用操作符的类,其对象常称为 函数对象(function object), 即它们的行为类似函数的对象。
14、标准库函数对象类型是在functional头文件中定义的, 每个标准库函数对象类表示一个操作符,即每个类都定义了应用命名操作的调用操作符。
15、标准库提供了一组 函数适配器(function adapter),用于特化和扩展一元和二元函数对象。函数适配器分为如下两类
① 绑定器( binder), 是一种函数适配器,它通过将一个操作数绑定到给定值而将二元函数对象转换为一元函数对象。 标准库定义了两个绑定器适配器: bind1st和bind2nd。
② 求反器(negator),是一种函数适配器,它将谓词函数对象的真值求反。 标准库定义了两个求反器: not1和not2。
16、 转换操作符(conversion operator) 是一种特殊的类成员函数。 它定义将类类型值转变为其他类型值的转换。 转换操作符在类定义体内声明,在保留字operator自后跟着转换的目标类型。
转换操作函数采用如下通用形式:
operator type();
转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空。
转换函数一般不应该改变被转换的对象,因此,
转换操作符通常应定义为const成员。
类类型转换之后不能再跟另一个类类型转换。如果需要多个类类型转换,则代码将出错。
17、既为算术类型提供转换函数,又为同一类类型提供重载操作符,可能会导致重载操作符和内置操作符之间的二义性。
2、作为类成员的重载函数,其形参看起来比操作数数目少1。 作为成员函数的操作符有一个隐含的this形参,限定为第一个操作数。
3、一般将算术和关系操作符定义为非成员函数,而将赋值操作符定义为成员。当操作符为成员函数,this指向左操作数。 操作符定义为非成员函数时,通常必须将它们设置为所操作类的友元。
4、重载逗号、取地址、逻辑与、逻辑或等操作符通常不是好做法。这些操作符具有有用的内置含义,如果women定义了自己的版本,就不能再使用这些内置含义。
5、下面是一些指导原则, 有助于决定将操作符设置为类成员还是普通非成员函数
① 赋值( =)、下标( [])、调用( ())和成员访问箭头( ->)等操作符必须定义为成员,将这些操作符定义为非成员函数将在编译时标记为错误。
② 像赋值一样,复合赋值操作符通常应定义为类的成员。与赋值不同的是,不一定非得这样做,如果定义非成员复合赋值操作符,不会出现编译错误。
③ 改变对象状态或与给定类型紧密联系的其他一些操作符,如自增、自减和解引用,通常应定义为类成员。
④ 对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通的非成员函数。
6、 输出操作符<<的重载:为了与IO标准库一致,操作符应接受ostream&作为第一个形参,对类类型const对象的引用作为第二个形参,并返回对ostream形参的引用。 一般而言,输出操作符应输出对象的内容,进行最小限度的格式化,它们不应该输出换行符。
7、 输入操作符>>的重载:与输出操作符类似,输入操作符的第一个形参是一个引用,指向它要读的流,并且返回的也是对同一个流的引用。它的第二个形参是对要读入的对象的非const引用,该形参必须为非const,因为输入操作符的目的是将数据读入这个对象中。
8、 为了与内置操作符保持一致,加法返回一个右值,而不是一个引用。 既定义了算术操作符又定义了相关复合赋值操作符的类,一般应使用复合赋值实现算术操作符。 定义了operator==的类更容易与标准库一起使用,有些算法,如find,默认使用==操作符,如果类定义了==,则这些算法可以无须任何特殊处理而用于该类类型。
9、关联容器以及某些算法,使用默认<操作符,一般而言,关系操作符,诸如相等操作符,应定义为非成员函数。
10、赋值操作符可以重载,无论形参为何种类型,赋值操作符必须定义为成员函数,这一点与复合赋值操作符有所不同。 一般而言,赋值操作符与复合赋值操作符应返回左操作数的引用。
11、类定义下标操作符时,一般需要定义两个版本: 一个为非const成员并返回引用, 另一个为const成员并返回const引用。
12、为了与内置类型一致,前缀式操作符应返回被增量或减量对象的引用。
例: parr.operator++(0);//call postfix operator++
13、函数调用操作符必须声明为成员函数。一个类可以定义函数调用操作符的多个版本,由形参的数目或类型加以区别。 定义了调用操作符的类,其对象常称为 函数对象(function object), 即它们的行为类似函数的对象。
14、标准库函数对象类型是在functional头文件中定义的, 每个标准库函数对象类表示一个操作符,即每个类都定义了应用命名操作的调用操作符。
15、标准库提供了一组 函数适配器(function adapter),用于特化和扩展一元和二元函数对象。函数适配器分为如下两类
① 绑定器( binder), 是一种函数适配器,它通过将一个操作数绑定到给定值而将二元函数对象转换为一元函数对象。 标准库定义了两个绑定器适配器: bind1st和bind2nd。
② 求反器(negator),是一种函数适配器,它将谓词函数对象的真值求反。 标准库定义了两个求反器: not1和not2。
16、 转换操作符(conversion operator) 是一种特殊的类成员函数。 它定义将类类型值转变为其他类型值的转换。 转换操作符在类定义体内声明,在保留字operator自后跟着转换的目标类型。
转换操作函数采用如下通用形式:
17、既为算术类型提供转换函数,又为同一类类型提供重载操作符,可能会导致重载操作符和内置操作符之间的二义性。