1.输入输出中的<<和>>是移位操作符的重载;
2.可以重载的操作符:
+ - * / % ^ & | ~ ! , = < > <= >= ++ -- << >> == != && || += -= /= %= ^= &= |= *= <<= >>= [] () -> ->* new new [] delete delete []
3.不能重载的操作符:
:: .* . ?:
4.通过连接其他合法符号可以创建新的操作符。例如,定义一个 operator**以提供求幂运算是合法的。
5.用于内置类型的操作符,其含义不能改变。例如,内置的整型加号操作符不能重定义
6.重载操作符必须具有至少一个类类型或枚举类型的操作数
7.除了函数调用操作符 operator()之外,重载操作符时使用默认实参是非法的。
8.重载操作符并不保证操作数的求值顺序, 重载 &&、|| 或逗号操作符不是一种好的做法。
9.作为类成员的重载函数,其形参看起来比操作数数目少 1。作为成员函数的操作符有一个隐含的 this 形参,限定为第一个操作数。
重载一元操作符如果作为成员函数就没有(显式)形参
10.当操作符为成员函数,this 指向左操作数。
11.操作符定义为非成员函数时,通常必须将它们设置为所操作类的友元。
12.也可以像调用普通函数一样调用重载操作符函数:cout << operator+(item1, item2) << endl;
13.重载操作符与内置操作符的相同之处:操作符的优先级,结合性和操作数数目均相同。
14.赋值操作符、取地址操作符和逗号操作符对类类型操作数有默认含义:
(1)合成赋值操作符默认进行逐个成员赋值:使用成员自己的赋值操作依次对每个成员进行赋值。
(2)默认情况下,取地址操作符(&)和逗号操作符(,)在类类型对象上的执行,与在内置类型对象上的执行一样。
(3)内置逻辑与(&&)和逻辑或(||)操作符使用短路求值(只有在仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数。我们常常称这种求值策略为“短路求值(short-circuit evaluation))。如果重新定义该操作符,将失去操作符的短路求值特征。
15.将要用作关联容器键类型的类应定义 < 和 == 操作符
16.赋值(=)、下标([ ])、调用(( ))和成员访问箭头(->)等操作符必须定义为成员
17.复合赋值操作符(+=)通常应定义为类的成员,但不一定非要这么做
18.改变对象状态或与给定类型紧密联系的其他一些操作符,如自增、自减和解引用,通常就定义为类成员。
19.对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通非成员函数。
20.输出操作符<<重载:为了与 IO 标准库一致,操作符应接受 ostream& 作为第一个形参,对类类型 const 对象的引用作为第二个形参,并返回对ostream 形参的引用: ostream& operator << ( ostream& os, const ClassType &object)
21.我们不能将输入输出操作符定义为类的成员.否则,左操作数将只能是该类类型的对象
22.输入操作符的第一个形参是一个引用,第二个形参是对要读入的对象的非const 引用,因为输入操作符的目的是将数据读到这个对象中。输入操作符必须处理错误和文件结束的可能性,如果出现了错误,我们可以将整个对象复位,
23.既定义了算术操作符又定义了相关复合赋值操作符的类,一般应使用复合赋值实现算术操作符
24.如果类定义了 operator==,它也应该定义 operator!=
25.赋值操作符和复合赋值操作符应返回对 *this 的引用,这就不需要创建和撤销结果的临时副本
26.类定义下标操作符时,一般需要定义两个版本:一个为非 const 成员并返回引用,另一个为 const 成员并返回 const 引用。
27.像下标操作符一样,我们需要解引用操作符和箭头操作符的 const 和非 const 版本
28.箭头操作符可能表现得像二元操作符一样:接受一个对象和一个成员名。不管外表如何,箭头操作符不接受显式形参。
因为-> 的右操作数不是表达式,而是对应着类成员的一个标识符
29.如果a是定义了 operator-> 操作符的类的一个对象, a->b相当于a. operator->()->b.
30.如果a是一个指针,a->b为a所指向的对象的b成员.
31.重载箭头操作符必须返回指向类类型的指针,或者返回定义了自己的箭头操作符的类类型对象
32.C++ 语言不要求自增自减操作符一定作为类的成员,但是,因为这些操作符改变操作对象的状态,所以更倾向于将它们作为成员。
33.前缀式操作符应返回被增量或减量对象的引用。后缀式操作符函数接受一个额外的(即,无用的)int 型形参。返回旧值(即,
尚未自增或自减的值),并且,应作为值返回,而不是返回引用。operator++(int)
34.定义了调用操作符的类,其对象常称为函数对象,即它们是行为类似函数的对象
35.转换操作符是一种特殊的类成员函数。它定义将类类型值转变为其他类型值的转换。转换操作符在类定义体内声明,在保留字 operator 之后跟着转换的目标类型:
class SmallInt {
public:
SmallInt(int i = 0): val(i)
{ if (i < 0 || i > 255)
throw std::out_of_range("Bad SmallInt initializer");
}
operator int() const { return val; }
private:
std::size_t val;
};
36.一般而言,不允许转换为数组或函数类型,转换为指针类型(数据和函数指针)以及引用类型是可以的。
37.转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空。
38.虽然转换函数不能指定返回类型,但是每个转换函数必须显式返回一个指定类型的值。例如,operator int 返回一个 int 值;
39.转换函数一般不应该改变被转换的对象。因此,转换操作符通常应定义为 const 成员。
40.只要存在转换,编译器将在可以使用内置转换的地方自动调用它:
//在表达式中:
SmallInt si;
double dval;
si >= dval// si converted to int and then convert to double
//在条件中:
if (si)// si converted to int and then convert to bool
//将实参传给函数或从函数返回值:
int calc(int);
SmallInt si;
int i = calc(si);// convert si to int and call calc
//作为重载操作符的操作数:
// convert si to int then call opeator<< on the int value
cout << si << endl;
//在显式类型转换中:
int ival;
SmallInt si = 3.541; //instruct compiler to cast si to int
ival = static_cast<int>(si) + 3;
41.类类型转换之后不能再跟
另一个类类型转换。如果需要多个类类型转换,则代码将出错。