C++ Primer读书笔记--第14章

(1)C++允许我们重新定义操作符用于类类型对象时的含义
(2)可以像内置转换一样使用类类型,将一个类型的对象隐式转换为另一个类型

标准库为容器定义了几个重载操作符:为容器定义了下标访问[],为迭代器定义了*和->

14.1  重载操作符的定义

重载操作符是具有特殊名称的函数:保留字operator后面接所需定义的操作符符号。

重载操作符的形参数目,与操作符的操作数相同。

不能重载的操作符  ::  .*  .  ?:

不建议重载的操作符:&& || & ,

几个基本经验:

(1)重载操作符最好不要改变内置类型的含义

(2)操作符的优先级、结合性或操作符数目不能改变

(3)重载操作符并不保证求值顺序,例如最短路等

(4)多数重载操作符可以定义为普通成员函数或类的成员函数

(5)重载操作符有两种:作为类的成员、非类的成员,其中后面的版本比前面的少一个参数,即this参数内置,一般将算术和关系运算定义为非成员,赋值运算定义为成员

(6)赋值(包括复合赋值如+=)一般返回类的引用,即左值;普通算术运算返回右值,即类类型。

(7)将操作符定义为非类成员的时候,一般要设置操作符为friend(在类内加friend就可以了),因为要访问private成员

如何调用重载操作符?

(1)和内置一样使用
cout<< item1+item2  <<endl;

(2)显示调用重载的符号函数
cout<< operator+(item1,item2) <<endl;

建议重载的操作符

因为STL算法需要部分操作符号的支持,所以建议重载下列操作符

(1)如果重载了==,也要重载!=
(2)sort等类似的算法需要重载小于号<

如何决定操作符为类成员还是非类成员

(1)赋值=,下标[],调用(),成员访问->必须定义为类成员,否则编译出错。
(2)复合赋值操作符通常应当定义为类成员
(3)改变对象状态或与给定类型密切联系的其他一些操作符,如++,--和引用&,通常应当定义为类成员
(4)对称的操作,如算术运算,相等运算,关系操作符,位操作符,最好定义为普通的非成员函数

14.2  输入和输出操作符

ostream & operator <<(ostream & os,const ClassType &object)
{
   //把object的成员输出
   os<<....;

   return os;
}
ostream & operator >>(istream & is,ClassType &object)
{
   //把输入从is读入到object的成员函数中
   return is;
}

读入必须处理出错

输入操作符必须处理错误和文件结束的可能性。

(1)任何读操作都可能因为提供的值不正确而失败(数值/非数值导致错误)
(2)任何读入都可能碰到文件结束或者其他错误

关于(1)处理读入错误的办法是:把形参恢复为空的读入类型对象,可以设置failbit。

关于(2)指出错误的方法是:设置eofbit。

14.3  算术操作符和关系操作符

为了与内置操作符保持一致,加法应该返回右值,而不是引用(左值),这个已经反复强调的。

复合运算符号,例如+=,可以调用+来实现,而不必创建一个临时结果。

相等操作符

inline bool operator==(const ClassType &lhs,const ClassType &rhs)
{
   return lhs.p1==rhs.p1 && lhs.p2==rhs.p2....
}

而重载operator !+的时候,可以return !(lhs==rhs);

<操作符

要谨慎对待,因为如果a<b且a>b,那么容器算法会认为a==b相等!

14.4  赋值运算符

注意:
(1)复合运算如+=也是赋值运算的一种
(2)赋值运算必须返回*this

ClassType& ClassType::operator+=(const ClassType &rhs)
{
   this->val1+=rhs.val1;
   return *this;
}

14.5  下标运算[]

注意,下标运算实际有两个版本,如下:

(1)a[3] = 10;
(2)cout << a[3];

(1)是[]返回了一个左值(引用)
(2)是[]返回了右值,右值是什么?就是const引用!

两个版本的重载函数原型如下:

class ClassType
{
public:

InnerType & operator [] (const size_t);

const InnerType & operator[] (const size_t);

private:

vector<InnerType> data;

 

未完待续。

Leave a Reply

Your email address will not be published. Required fields are marked *