C++操作符重载

重载操作符是具有特殊名称的函数:保留字operator后接需定义的操作符符号。除了函数调用操作符之外,重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数数目相同。函数调用操作符可以接受任意数目的操作数。

 

大多数操作符都可以重载,所以我列出不能重载的操作符,一共有四种:

::                        .*                            .                            ?:

 

当操作符为类的成员函数时,this指向左操作数。

 

下面通过实例说明操作符重载

源代码下载:点击下载

1.算术操作符

定义一个Point类,Point.h头文件:

// Point.h: interface for the Point class.
//
//

#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源文件:

// Point.cpp: implementation of the Point class.
//
//

#include "Point.h"

//
// Construction/Destruction
//

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;
	//cout<<(pt1==pt2)<<endl<<(pt1==pt1)<<endl<<(pt1!=pt2)<<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);
	
//	++pt1;
//	--pt2;
	//cout<<pt1.getX()<<pt1.getY()<<endl<<pt2.getX()<<pt2.getY()<<endl;
	//cout<<(pt1==pt2)<<endl<<(pt1==pt1)<<endl<<(pt1!=pt2)<<endl;
	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]是右值。表现正常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值