C++笔记(三)重载操作符

1.操作符重载:把操作符赋予新的意义

2.可重载和不可重载


3.用于内置类型的操作符,其含义不能改变。例如,内置的整型加号操作符不能重定义:int oprator+(int,int);//error:cannot redefine built-in operator for ints

 也不能为内置数据类型重定义加号操作符。例如,不能定义接受两个数组类型操作数的operator+。

4.操作符的优先级、结合性或操作数数目不能改变。不管操作数的类型和操作符的功能定义如何,例如:x == y + z;  总是将y和z绑定到operator+,结果再作为operator==的右操作数。同时也不具备短路求值特性,例如:&&和||重载后,两个操作数都会进行求值。

5.当操作符重载函数作为类的成员函数时,操作符重载函数的参数会比作为友元或者独立于类的操作符重载函数少一个参数,因为操作符重载类成员函数把调用该函数的第一个类的对象作为函数的第一个参数,也就是隐含的this指针指向调用该函数的第一个对象,所以会少一个参数。

例如:item& item::operator+(const item&);//成员

           item operator+(const item&,const item&);//非成员

6.操作符定义为非成员函数时,通常必须将它们设置为所操作类的友元,在这种情况下,操作符通常需要访问类的私有部分。友元部分见上一篇博文C++笔记(二)友元

7.某些情况下操作符函数必须返回一个对象类型作为返回值,比如item对象,a=b+c;重载+操作符就必须返回一个item类型的对象,以便赋给对象a,不然该语句就会出错。当然你可以在语句中返回一个临时对象,也可以返回一个对象的引用,或者返回this指针,不过返回临时对象会浪费内存开销,所以最好返回类对象的一个引用。

8.操作符函数可以按值传递也可以按引用传递,这根据操作符而定,比如对于+运算符既可以把对象按值传递给操作符函数也可以按引用传递给操作符函数,而且+操作符不会改变原操作数的值,所以应把传递类型生命为const,例如:item operator+(const item& a,const item& b)。但对于要改变其自身值的操作符比如++运算符,就必须传递引用,且不能把该引用声明为const类型,因为如果操作数按值传递的话,传递给操作数函数的将是一个对象的副本,两个副本是独立的,不能改变到远对象的值,所以应按引用传递对象,

例如:item operator++(item& a)。

9.输入和输出操作符:

支持I/O操作的类所提供的I/O操作接口,一般应该与标准库iostream为内置类型定义的接口相同,因此,许多类都需要重载输入和输出操作符。IO操作符必须为非成员函数。

输出操作符<<的重载:为了与IO标准库一致,操作符应接受ostream&作为第一个形参,对类类型const对象的引用作为第二个形参,并返回对ostream形参的引用。

ostream& operator<<(ostream& out,const item& s)

{

out<<s.isbn<<"\t"<<s.units_sold<<"\t"<<s.revenue<<"\t"<<s.avg_prive();

return out;

}

输入操作符>>的重载:与输出操作符类似,但是输入操作符必须处理错误和文件结束的可能性。

istream& operator>>(istream& in,item& s)

{

double price;

in>>s.isbn>>s.units_sold>>price;

if(in)

s.revenue = s.units_sold * price;

else

s = item();//相当于复位

return in;

}

10.算术操作符:

算术操作符一般定义为非成员函数。

item operator+(const item& lhs,const item& rhs)

{

item ret(lhs);

ret += rhs;

return ret;

}

加法操作符不改变操作数的状态,操作数是对const对象的引用;相反它产生并返回一个新的item对象,该对象初始化为lhs的副本。我们使用item的符合赋值操作符来加入rhs的值。注意,为了与内置操作符保持一致,加法返回一个右值,而不是一个引用。

11.相等操作符:

比较对象中的每个数据成员,如果所有对应成员都相同,则认为两个对象相等。

inline bool operator==(const item &lhs,const item &rhs)

{

return lhs.units_sold == rhs.units_sold && lhs.revenue == rhs.revenue && lhs.same_isbn(rhs);

}

inline bool operator!=(const item &lhs,const item &rhs)

{

return !(lhs ==rhs);

}

12.赋值操作符:

类赋值操作符接受类类型形参,通常,该形参是对类类型的const引用,但也可以是类类型或对类类型的非const引用。如果没有定义这个操作符,则编译器将合成它。类赋值操作符必须是类的成员,以便编译器可以知道是否需要合成一个。

class string

{

public:

string& operator=(const string&);   //s1 = s2;

string& operator=(const char*);   //s1 = "str";

string& operator=(char);   //s1 = 'c';

//......

};

注:赋值操作符可以重载。无论形参为何种类型,赋值操作符必须定义为成员函数,这一点与复合赋值操作符(+=)有所不同。

赋值必须返回对*this的引用:

string赋值操作符返回string引用,这与内置类型的赋值一致。而且,因为赋值返回一个引用,就不需要创建和撤销结果的临时副本。返回值通常是左操作数的引用。

例如:

item& item::operator+=(const item& rhs)

{

units_sold += rhs.units_sold;

revenue += rhs.revenue;

return *this;

}

一般而言,赋值操作符与符合操作符应返回左操作数的引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章