C++集锦三 操作符重载
来源:互联网 发布:exe软件看源码 编辑:程序博客网 时间:2024/06/07 01:11
重载操作符是具有特殊名称的函数:保留字operator后接需定义的操作符符号。除了函数调用操作符之外,重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数数目相同。函数调用操作符可以接受任意数目的操作数。
大多数操作符都可以重载,所以我列出不能重载的操作符,一共有四种:
:: .* . ?:
当操作符为类的成员函数时,this指向左操作数。
下面通过实例说明操作符重载
源代码下载:点击下载。
1.算术操作符
定义一个Point类,Point.h头文件:
-
-
-
-
- #if !defined(AFX_POINT_H__E8270DD2_C889_4B24_BC82_E154B77FDFCF__INCLUDED_)
- #define AFX_POINT_H__E8270DD2_C889_4B24_BC82_E154B77FDFCF__INCLUDED_
-
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
-
- class Point
- {
- public:
- Point();
- Point(int x,int y);
- virtual ~Point();
- int getX();
- int getY();
- Point operator+(const Point&);
- private:
- int x,y;
-
- };
-
- #endif // !defined(AFX_POINT_H__E8270DD2_C889_4B24_BC82_E154B77FDFCF__INCLUDED_)
Point.cpp源文件:
-
-
-
-
- #include "Point.h"
-
-
-
-
-
- Point::Point()
- {
-
- }
- Point::Point(int x,int y)
- {
-
- this->x=x;
- this->y=y;
- }
-
- Point::~Point()
- {
-
- }
- Point Point::operator +(const Point &pt)
- {
- Point p(*this);
- p.x+=pt.x;
- p.y+=pt.y;
-
- return p;
- }
-
- int Point::getX()
- {
-
- return this->x;
- }
- int Point::getY()
- {
- return this->y;
- }
在这里,我要重载Point类的加号操作符,实现两个点的x和y分别相加,返回一个Point对象,返回的Point对象的x为两个Point的x的和,y为两个Point的y相加。
主类:
- #include<iostream>
- #include<algorithm>
- #include "Point.h"
- using namespace std;
-
-
- int main()
- {
-
- Point pt1(3,4);
- Point pt2(4,5);
- Point pt3=pt1+pt2;
-
- cout<<pt3.getX()<<endl<<pt3.getY()<<endl;
- return 0;
- }
在这里要注意了,不能返回一个局部自定义类型的引用或者指针,因为函数结束之后,内存被释放,再去使用的话,会出现不可预知的错误。
2.关系操作符
在头文件中定义两个函数:
- bool operator==(const Point&);
- bool operator!=(const Point&);
在源文件中实现这个函数:
- bool Point::operator==(const Point &pt)
- {
- return this->x==pt.x&&this->y==pt.y;
- }
-
- bool Point::operator!=(const Point &pt)
- {
- return !(*this==pt);
- }
因为前面定义了==的操作符,所以后面的!=操作符可以使用==操作符。在定义关系操作符的时候一定要注意如果==返回真,则!=返回假。
3.自增操作符和自减操作符
这样的操作符的难点是这两个符号既可以在对象之前,也可以在对象之后,我先实现在对象之前的操作符重载。
在头文件中定义函数:
- Point& operator++();
- Point& operator--();
在源文件中如此实现:
- Point& Point::operator ++()
- {
- this->x++;
- this->y++;
- return *this;
- }
- Point& Point::operator --()
- {
- x--;
- y--;
- return *this;
-
- }
在主函数中测试如下:
- #include<iostream>
- #include<algorithm>
- #include "Point.h"
- using namespace std;
-
-
- int main()
- {
-
- Point pt1(3,4);
- Point pt2(4,5);
-
- ++pt1;
- --pt2;
- cout<<pt1.getX()<<pt1.getY()<<endl<<pt2.getX()<<pt2.getY()<<endl;
-
-
- return 0;
- }
同时定义前缀式操作符与后缀式操作符存在一个问题:他们的形参数目和类型相同,普通重载不能区别所定义的是前缀式操作符还是后缀式操作符。
为了解决这一问题,后缀式操作符接受一个额外的int形参。使用后缀式操作符时,编译器提供0作为这个形参的实参。尽管我们的前缀式操作符可以使用这个额外的形参,但通常不应该这样做。那个形参不是后缀式操作符的正常工作所需要的,它的唯一作用是使后缀式函数与前缀式函数区别开。
在头文件中定义如下:
- Point operator++(int);
- Point operator--(int);
在源文件中实现:
- Point Point::operator ++(int)
- {
- Point p(*this);
- ++*this;
- return p;
-
- }
-
- Point Point::operator --(int)
- {
-
- Point p(*this);
- --*this;
- return p;
- }
在主函数中测试成功:
- #include<iostream>
- #include<algorithm>
- #include "Point.h"
- using namespace std;
-
-
- int main()
- {
-
- Point pt1(3,4);
- Point pt2(4,5);
-
-
-
-
-
- Point pt3=pt1--;
- cout<<pt3.getX()<<endl<<pt3.getY()<<endl;
- return 0;
- }
打印的是pt1自减之前的值。
注意:使用对象显式调用后缀式自减或自加时,应该传入一个参数:
Point pt;
pt.operator++(0); 这样就是调用后缀式的操作。
4.下标操作符
小标操作应该注意,在用作赋值的左右操作数时,都应该表现的正常。所以,这就要求返回的类型应该为引用。
小面定义一个类China,包含省级行政单位,定义在hina.h头文件中:
- #if !defined(AFX_HINA_H__2E76F1BB_EE30_4584_9C8F_C46A4C613620__INCLUDED_)
- #define AFX_HINA_H__2E76F1BB_EE30_4584_9C8F_C46A4C613620__INCLUDED_
-
- #if _MSC_VER > 1000
- #pragma once
- #endif
- #include <string>
- class China
- {
- public:
- China();
- std::string& operator[](const int index);
- virtual ~China();
- private:
- std::string *province;
-
-
- };
-
- #endif
源文件为hina.cpp,如下实现:
- #include "hina.h"
- China::China()
- {
- province=new std::string[34];
- province[0]=std::string("山西省");
- province[1]=std::string("湖北省");
- province[2]=std::string("北京市");
-
- }
-
- China::~China()
- {
- delete []province;
- }
-
- std::string& China::operator [](const int index)
- {
- if(index<0||index>34)
- return std::string("有错误");
-
- return province[index];
- }
这样就保证下标返回返回的值既可以是左值,又是右值。在main函数中测试通过:
- #include <iostream>
- #include "hina.h"
- using namespace std;
- int main()
- {
- China c;
- c[0]="张译成";
- cout<<c[0]<<endl;
- return 0;
- }
我将山西省换成我的名字,就改变了c对象中的值,c[0]="张译成";中,c[0]是左值,cout<<c[0]<<endl;中c[0]是右值。表现正常。