首页 > 代码库 > C++笔记(3):运算符重载
C++笔记(3):运算符重载
运算符重载
1.运算符重载基础
2.运算符重载的规则
3.重载双目运算符
4.重载单目运算符
5.重载流插入和提取运算符
6.类型转换
7.定义自己的string类
-------------------------------------------------------------------------------------------------------------------------------
1.运算符重载基础
运算符重载就是对已有的运算符赋予新的含义,实现新的功能。
前面我们已经使用过运算符重载,如“+”,它可以对int、float、string类型进行加法运算。<<是C++中的左移运算符,但是在输出操作中与cout配合被称为流插入运算符,可以进行输出。>>是右移运算符,与cin配合使用被称为流提取运算符。
它们都被称为运算符重载。
我们也可以根据我们的需要对C++中现有的运算符进行重载,来赋予这些运算符新的含义。如CTime类,重载+运算符,实现两个CTime对象的相加。
介绍运算符重载前,我们看下如何来实现两个CTime对象相加。
CTime重载+运算符实现两个CTime对象的相加,
time1 + time2
首先需要定义一个重载的运算符函数,此后在执行被重载的运算符时,系统将自动调用该运算符函数。
运算符重载实际上是函数的重载。
运算符重载的格式
返回类型 operator运算符(参数列表)
CTime operator+(CTime& time1, CTime& time2)
重载的运算符函数可以作为一般的函数,也可以作为类的成员函数。
CTime operator+(CTime& time)
-------------------------------------------------------------------------------------------------------------------------------
2.运算符重载的规则
被重载的运算符必须是已经存在的C++运算符,不能重载自己创建的运算符。
运算符被重载之后,原有功能仍然保留。只是扩展了原有功能。
重载不能改变运算符运算对象的个数。+运算符具有两个操作数,在+运算符函数作为CTime的成员函数的时候,有一个参数是隐含的,也就是当前的对象,使用this来引用。另一个参数通过函数参数指定。
可以重载的运算符:
1.算术运算符:+,-,*,/,%,
2.逻辑运算符:&&,||,!
3.关系运算符:>,<,=,>=,<=,==,!=
4.位操作符:~,<<,>>,&,^),|
5.自增自减运算符:++,--
6.复合赋值运算符:+=,-=,*=,/=,%=
7.其他:&、*、 () 、-> 、[]、.new/delete、>>、<<
不能重载的运算符:?: . * :: sizeof
不需要重载的运算符:=(赋值)和&(取地址符)
赋值函数
普通函数和类的成员函数都可以作为类的友元,但什么时候应该使用普通函数,什么时候应该使用成员函数方式呢?
普通函数形式的运算符函数一般都声明为类的友元函数,用以访问类的私有数据成员。这样可以减低开销,但破坏封装性。
因此建议尽量使用成员函数形式。
一般将单目运算符重载为成员函数,将双目运算符重载为友元函数。
成员函数方式要求左侧的参数要与类类型相同。
而普通函数则要求实参顺序与形参类型顺序一致。
如
有的运算符必须定义为类的成员函数:=、[]、()
有的运算符不能定义为类的成员函数,只能定义为类的友元:<<、>>
运算符重载可以执行任意的操作,比如可以将+定义成两个对象相减的操作,但是这样违背我们日常使用的习惯,容易使用误用,减低程序可读性,因此必须保证重载的运算符与该运算符应用于标准数据类型时所具有的功能。
-------------------------------------------------------------------------------------------------------------------------------
3.重载双目运算符
所谓双目运算符就是具有两个操作数的运算符。如 +、-、==等
重载双目运算符时,运算符函数中应该具有两个参数,若运算符函数作为类的成员函数,则只需要一个参数。
实例
重载 == 、>、<运算符
-------------------------------------------------------------------------------------------------------------------------------
4.重载单目运算符
所谓单目运算符就是具有一个操作数的运算符。如 !、++、--、+=等
重载单目运算符时,运算符函数中应该具有一个参数,若运算符函数作为类的成员函数,则没有参数。
实例
重载++、+=运算符
-------------------------------------------------------------------------------------------------------------------------------
5.重载流插入和提取运算符
流插入运算符<<和流提取运算符>>也可以被用来重载。
可以为CTime类定义重载的流插入和流提取运算符。
重载之后就可以直接对CTime对象进行输入和输出:
cout<<time;
cin>>time;
前面一节我们在介绍运算符重载的规则时介绍过,重载流插入和提取运算符的运算符函数,不能作为类的成员函数,只能作为普通函数。
<<和>>重载的函数声明如下:
istream& operator>> (istream& input, CTime& time);
ostream& operator<<(ostream& output, CTime& time);
istream和ostream分别是输入流类和输出流类。cin和cout就分别是istream和ostream的对象。
重载>>流提取运算符的函数第一个参数和返回类型必须是istream&类型。
重载<<流插入运算符的函数第一个参数和返回类型必须是ostream&类型。
在重载完流插入和提取运算符后,我们就可以对该类使用<<输出数据,使用>>输入数据。这样是非常直观的。
cout<<time;
operator<<(cout, time);
cin>>time;
operator>>(cin, time);
-------------------------------------------------------------------------------------------------------------------------------
6.类型转换
1.使用构造函数进行类型转换
在为CTime类重载+运算符后,我们就可以对两个CTime对象使用+运算符进行操作。
但仍然不能使用+运算符将一个CTime对象和一个int类型相加。为了实现它,我们可以先将int类型转换为一个CTime的临时对象,然后在进行相加。如下:time + CTime(2)
CTime(2)这种形式很类似于强制类型转换,将int类型转换为CTime类型。之所以可以进行此种转换,是因为我们已经为CTime对象定义了具有一个int类型参数的构造函数。因此具有一个参数的构造函数可以用来做类型转换,称之为转换构造函数。
有了类型转换函数,在需要CTime类型参数的地方可以使用int类型代替。
2.类型转换函数进行类型转换
类型转换函数用以将类的对象转换另一种数据类型的函数。如可以将CTime类对象转换int类型。
int nSecond = time;
operator int()
没有参数,没有返回类型。
-------------------------------------------------------------------------------------------------------------------------------
7.定义自己的string类
string类使用起来比较方便,在本课程的开始我们就学习了string类。
目前为止,我们学习了如何定义类,以及如何为类定义运算符重载函数。
今天我们就来定义一个类似于string功能的自己的String类。
构造函数:
String(const char *s); //用c字符串s初始化
String(int n,char c); //用n个字符c初始化
拷贝和赋值
String& String(String& str);
const String& operator=(String& str);
析构函数
~String();
下标访问:
char &operator[](int n);
char &at(int n)const;
String类提供的方法:
int size()const; //返回当前字符串的大小
int length()const; //返回当前字符串的长度
bool empty()const; //当前字符串是否为空
重载流插入和提取运算符:
istream& operator>>(istream& input, String& str);
ostream& operator<<(ostream& output, String& str)
连接两个字符串:
String &operator+=(String &s);
字符串比较:
bool operator==(const String &s1,const String &s2)const;
int compare(const string &s) const;//比较当前字符串和s的大小
-------------------------------------------------------------------------------------------------------------------------------
C++笔记(3):运算符重载