C++ 一元、二元运算符重载

运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,使他适应不同的数据类型。

运算符重载的本质:函数重载       关键字:operator

一、一元运算符重载

一元运算符就是对一个数进行操作

一元运算符重载利用成员函数进行重载时,就不用给()内传参数了,()内有隐藏的*this

负号运算符的重载

定义一个Coordinate坐标类,分别通过成员函数和友元函数对负号运算符进行重载

通过成员函数对负号运算符进行重载:

#include<iostream>
using namespace std;

/******************************************
一元运算符重载
要求:
定义一个Coordinate坐标类
成员函数:构造、getX、getY,数据成员:m_iX,m_iY
1、负号运算符重载(成员函数,友元函数)
2、++运算符重载(前置++,后置++)
*******************************************/

class Coordinate
{
	Coordinate(int x,int y);

        //通过成员函数对符号运算符进行重载 
	Coordinate &operator-();//让他返回出来的是它本身,这样才能让他再进行负号运算符的运算,所以返回值写成Coordinate &

	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

//成员函数实现负号运算符重载
Coordinate &Coordinate::operator-()
{
	this->m_iX = -(this->m_iX);//m_iX = -m_iX;
	this->m_iY = -(this->m_iY);

	return *this;//返回的是一个对象
}


int main()
{
	Coordinate coor1(1,3);
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;
	-coor1;//coor1.operator-();成员函数
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;

	return 0;
}

运行结果:

通过友元函数对负号运算符进行重载:


#include<iostream>
using namespace std;

/******************************************
一元运算符重载
要求:
定义一个Coordinate坐标类
成员函数:构造、getX、getY,数据成员:m_iX,m_iY
1、负号运算符重载(成员函数,友元函数)
2、++运算符重载(前置++,后置++)
*******************************************/

class Coordinate
{
	friend Coordinate &operator-(Coordinate &c);//friend Coordinate &operator-(Coordinate c);
	//()内要传入参数,其实就是在成员函数重载中要传入的*this,所以应该是Coordinate的一个对象,为了传递效率,也可以传入一个对象的引用
public:
	Coordinate(int x,int y);
	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

Coordinate &operator-(Coordinate &c)//友元函数重载符号运算符
{
	c.m_iX = -c.m_iX;
	c.m_iY = -c.m_iY;

	return c;
}

int main()
{
	Coordinate coor1(1,3);
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;

	operator-(coor1);//-coor1;
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;

	return 0;
}

运行结果:

前置++、后置++重载

#include<iostream>
using namespace std;

Coordinate
{
public:
	Coordinate(int x,int y);
	Coordinate &operator++();//前置++的运算符重载,返回的是一个Coordinate的引用
	Coordinate operator++(int);//后置++的运算符重载,参数int只是为了表示当前的++是后置++
//返回的是一个对象而不是引用,是因为后置++是在下一行代码再去访问这个对象的时候才会返回++之后的值,如果返回引用的话,函数结束后,引用就会被释放
	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

Coordinate &Coordinate::operator++()//前置++
{
	++m_iX;
	++m_iY;

	return *this;
}
Coordinate Coordinate::operator++(int)//后置++
{
	Coordinate old(*this);//利用默认拷贝构造函数构造一个临时对象old,将++之前的值存储在临时对象old中
	this->m_iX++;
	this->m_iY++;

	return old;//当前这个表达式是他++之前的值,下一行代码再去访问这个对象的时候,才是++之后的值
}


int main()
{
	Coordinate coor1(1,3);
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;//1,3

	coor1.operator++(0);//参数0只是标识是后置++
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;//2,4
	
	cout<<(coor1++).getX()<<",";//2
	cout<<(coor1++).getY()<<endl;//5

	return 0;
}

运行结果:

二、二元运算符重载

1、“+号”运算符重载(成员函数,友元函数)
2、“<<”输出运算符重载
3、“[]索引”运算符重载

#include<iostream>
using namespace std;

/******************************************
二元运算符重载
要求:
定义一个Coordinate坐标类
成员函数:构造、getX、getY,数据成员:m_iX,m_iY
1、“+号”运算符重载(成员函数,友元函数)
2、“<<”输出运算符重载
3、“[]索引”运算符重载
*******************************************/

class Coordinate
{
	//“<<”输出运算符重载
	friend ostream& operator<<(ostream &output,const Coordinate &c);//返回值是ostream

	//“+号”运算符通过友元函数重载
	friend Coordinate operator+(const Coordinate &c1,const Coordinate &c2);
public:
	Coordinate(int x,int y);

	//“+号”运算符通过成员函数重载,不能传引用,要传对象
	//Coordinate operator+(const Coordinate &c);

	//“[]索引”运算符重载
	int operator[](int index);

	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

/*“+号”运算符通过成员函数重载
Coordinate Coordinate::operator+(const Coordinate &c)
{
	Coordinate temp(0,0);
	temp.m_iX = this->m_iX + c.m_iX;
	temp.m_iY = this->m_iY + c.m_iY;

	return temp;
}
*/

//“+号”运算符通过友元函数重载
Coordinate operator+(const Coordinate &c1,const Coordinate &c2)
{
	Coordinate temp(0,0);
	temp.m_iX = c1.m_iX + c2.m_iX;
	temp.m_iY = c1.m_iY + c2.m_iY;

	return temp;
}

//“<<”输出运算符重载
ostream& operator<<(ostream &output,const Coordinate &c)//返回值为ostream&,const Coordinate &c为要进行输出的对象
{
	output<<c.m_iX<<","<<c.m_iY<<endl;
	return output;
}

//“[]索引”运算符重载
int Coordinate::operator[](int index)
{
	if(0 == index)
	{
		return m_iX;
	}
	if(1 == index)
	{
		return m_iY;
	}
}

int main()
{
	Coordinate coor1(1,3);
	Coordinate coor2(2,4);
	Coordinate coor3(0,0);
	coor3 = operator+(coor1,coor2);
	//coor3 = coor1 + coor2;
	cout<<coor3.getX()<<","<<coor3.getY()<<endl;//3,7

	operator<<(cout,coor1);//1,3
	cout<<coor2;//2,4

	cout<<coor2[0];//2
	cout<<coor2[1];//4

	return 0;
}

运行结果:

注:

  1. “<<”输出运算符重载不能用成员函数进行重载,只能用友元函数进行重载;因为在成员函数中重载第一个参数为隐藏的*this,而“<<”输出运算符重载第一个参数为ostream &output
  2. “[]索引”运算符重载不能用友元函数进行重载,只能用成员函数进行重载;因为“[]索引”运算符重载第一个参数必须为*this,通过*this才能访问到该对象的数据
  3. 赋值运算符重载函数不能被继承

    因为相较于基类,派生类往往要添加一些自己的数据成员和成员函数,如果允许派生类继承基类的赋值运算符重载函数,那么,在派生类不提供自己的赋值运算符重载函数时,就只能调用基类的,但基类版本只能处理基类的数据成员,在这种情况下,派生类自己的数据成员怎么办?                        所以,C++规定,赋值运算符重载函数不能被继承。

  4. 赋值运算符重载函数只能是类的非静态的成员函数,不能是静态成员函数,也不能是友元函数

     

    其实,之所以不是静态成员函数,是因为静态成员函数只能操作类的静态成员,不能操作非静态成员。如果我们将赋值运算符重载函数定义为静态成员函数,那么,该函数将无法操作类的非静态成员,这显然是不可行的。

     

三、可重载运算符/不可重载运算符

下面是可重载的运算符列表:

双目算术运算符+ (加),-(减),*(乘),/(除),% (取模)
关系运算符==(等于),!= (不等于),< (小于),> (大于>,<=(小于等于),>=(大于等于)
逻辑运算符||(逻辑或),&&(逻辑与),!(逻辑非)
单目运算符+ (正),-(负),*(指针),&(取地址)
自增自减运算符++(自增),--(自减)
位运算符| (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移)
赋值运算符=, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
空间申请与释放new, delete, new[ ] , delete[]
其他运算符()(函数调用),->(成员访问),,(逗号),[](下标)

下面是不可重载的运算符列表:

  • .:成员访问运算符
  • .*, ->*:成员指针访问运算符
  • :::域运算符
  • sizeof:长度运算符
  • ?::条件运算符
  • #: 预处理符号

还可参考:一文说尽C++赋值运算符重载函数(operator=) 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值