关闭

C++ primer:重载

315人阅读 评论(0) 收藏 举报

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.类类型转换之后不能再跟另一个类类型转换。如果需要多个类类型转换,则代码将出错。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:109095次
    • 积分:1616
    • 等级:
    • 排名:千里之外
    • 原创:48篇
    • 转载:31篇
    • 译文:0篇
    • 评论:19条
    文章分类
    最新评论