c++运算符重载

C++为了增加代码的可读性引入运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与普通的函数类似。
运算符重载即给某个运算符定义一个新的算法,让它能做原本不能做的运算。
运算符重载的关键字为operator,它的后面跟着你想重载的运算符,可以在类内重载,也可以在内外重载,像左移和右移运算符一般在类外重载,加减乘除可在类内重载。
1、加号重载
代码如下

Person operator+(Person &p1,int b){
	Person temp;
	temp.m_a=p1.m_a+b;
	temp.m_b=p1.m_b+b;
	return temp;
}

其中int b可以改为Person &p2或者其他,同时应在类中添加友元,后面的也都是。
2、左移/右移运算符重载
左移运算符即<<,它属于头文件iostream里面的ostream类。故代码应如下:

ostream &operator<<(ostream &cout,Person &p){
	cout<<p.m_A<<" "<<p.m_B;
	return cout;
}

为啥要用ostream作为返回值呢?我的理解是要连续输出,如果用void做返回值那么只能输出一次不能实现cout<<()<<()<<()<<…<<endl;的操作,即无法追加输出,只能实现cout<<对象;的操作
右移与之类似,只是ostream改为了istream,二者分别对应输出流和输入流。
3、递增/递减运算符重载
代码如下:

Person &operator++(Person &p){
		p.m_A++;
			return p;
		}
Person operator++(Person &p,int){
		Person temp=p;
		p.m_A++;
		return temp;
		}

其中第一个是前置递增,第二个是后置递增。第二个要注意,一是要在参数列表里添加一个占位参数int,为什么呢?我在一篇博客上找到了答案:
重载主要是两者形参上的区别:
前置++没有形参,而后置++有一个int形参,但是该形参也没有被用到。很奇怪,难道有什么特殊的用意?
其实也没有特殊的用意,只是为了绕过语法的限制。
前置++与后置++的操作符重载函数,函数原型必须不同。否则就违反了“重载函数必须拥有不同的函数原型”的语法规定。
虽然前置++与后置++的返回类型不同,但是返回类型不属于函数原型。为了绕过语法限制,只好给后置++增加了一个int形参。
原因就是这么简单,真的没其他特殊用意。其实,给前置++增加形参也可以;增加一个double形参而不是int形参,也可以。只是,当时就这么决定了。

4、赋值运算符重载
赋值运算符重载我一般写在类里面,应为我写在类外总是会出现错误,阿巴阿巴,不管它啦。代码如下:

class Person {
	public:	
	int *m_A;
	Person(int a){
		m_A=new int(a); 
	}
	~Person(){
		if(m_A!=NULL){
			delete m_A;
			m_A=NULL;
		}
	}
	Person &operator=(Person p){
		if(m_A!=NULL){
			delete m_A;
			m_A=NULL; 
		}
		m_A=new int(*p.m_A);
		return *this;
	}
};

其实,由于编译器为我们提供了一份赋值运算符,如果我们不写编译器会自动调用它,但这样就会出现浅拷贝问题,即内存空间重复释放,但如果你不写析构函数也不会重复释放2333,但这样又会出现内存泄漏的问题,我们是严谨的程序猿,所以我们要自己写赋值运算符重载,这也就是深拷贝,在堆区new一块内存,这样就解决了重复释放的问题,这个东西在我的构造函数浅理解中也说到过,有兴趣的小伙伴可以看看呀。
5、关系运算符(==和!=)重载
代码如下:

//类内
bool operator==(Person &p){
	if(this->m_age==p.m_age&&this->m_name==p.m_name)
	return true;
	else return false;
	}
bool operator!=(Person &p){
	if(this->m_age==p.m_age&&this->m_name==p.m_name)
	return false;
	else return true;
	}

没啥好说的,记得用bool作为返回值。
6、函数调用运算符重载
函数调用运算符就是函数后面的那个(),由于他使用的时候很像函数调用,故而又称仿函数,仿函数的写法十分灵活,没有固定写法,下面给出一种示例:

class Myadd{
	public:
		int operator()(int a,int b){
			return a+b;
		}
};
void test02(){
	Myadd m;
	int ret=m(10,10);
	int p=Myadd()(ret,ret);//匿名对象
	cout<<ret<<endl;
	cout<<p<<endl;
}

最后运算符重载不是想让什么重载就让什么重载比如:
. :成员访问运算符
. *, ->:成员指针访问运算符
:: :域运算符
sizeof :长度运算符
?: :条件运算符
#: 预处理符号
不能重载。
还有什么@啊啥啥的也不能重载,建议最好不要随意重载,比如加号重载为减号等等,要增加代码的可读性。
最后黄字转自:为什么后置++和后置–是单目运算符却有一个int形参

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值