C++运算符重载

运算符重载

作用:用户自己编写运算符功能,两个类之间直接用普通运算符不行,那就重载运算符
用法:将 成员函数/全局函数 名起为 operator<符号>

加号运算符重载

#include <iostream>
using namespace std;

class person {
public:
	int num;
};

person operator+ (const person &p1,const person &p2) {
	person* temp = new person;
	temp->num = p1.num + p2.num;
	return *temp;
}

void main() {
	person p1;
	p1.num = 10;
	person p2;
	p2.num = 13;

	person p3 = p1 + p2;//本质上p3=operator+(p1,p2)
	cout<<p3.num<<endl;
}	

注意:运算重载的函数也能重载

左移运算符重载

#include <iostream>
using namespace std;

class person {
public:
	int num;
};
//返回值为ostream& cout,能够进行链式编程
ostream& operator<<(ostream &cout, const person& p) {//重载了<<,简化可写cout<<p
	cout << p.num << endl;
	return cout;
}

void main() {
	person p1;
	p1.num = 10;
	cout<<p1;//如果不写返回值为ostream& cout就只能这样写
	cout<<p1<<endl;//如果不写返回值为ostream& cout这样写会报错
}

递增运算符重载

#include <iostream>
using namespace std;

class person {
	friend ostream& operator<<(ostream& cout, const person& p);
private: 
	int num;
public:
	person(int num):num(num) {}
	//前置
	person& operator++() {
		num++;
		return *this;
	}
	//后置
	person operator++(int) {//加入了占位参数之后,就变成后置递增了
		person temp = *this;//返回一个当前值,没有自加的
		num++;//但是本事这个类实例是已经递增的了
		return temp;//通过这种手法实现了后置递增
	}
};

ostream& operator<<(ostream &cout, const person& p) {
	cout << p.num << endl;
	return cout;
}

void main() {
	person p1(10);
	cout<<++p1<<endl;
	cout<<p1++<<endl;
	cout << p1 << endl;
}

赋值运算符重载

有问题的操作,析构函数重复释放堆区内存

#include <iostream>
using namespace std;

class person {
	friend ostream& operator<<(ostream& cout, const person& p);
private: 
	int *num;
public:
	person(int num){
		this->num = new int(num);
	}
	~person() {
		if (this->num != NULL)
			delete(this->num);
	}
};

ostream& operator<<(ostream &cout, const person& p) {
	cout << *p.num;
	return cout;
}

void main() {
	person p1(10);
	person p2(12);			/*这样会报错,因为析构的时候会重复释放this->num指向的内存空间*/
							/*系统默认的拷贝函数是浅拷贝,更改的只是指针的指向,所以两个类*/
	p2=p1;					/*的num指针指向同一块内存									*/
	cout << p1 << endl;
	cout << p2 << endl;
}

重载后

#include <iostream>
using namespace std;

class person {
	friend ostream& operator<<(ostream& cout, const person& p);
private: 
	int *num;
public:
	person(int num){
		this->num = new int(num);
	}
	~person() {
		if (this->num != NULL)
			delete(this->num);
	}
	//赋值符号重载操作,返回值使得其能够进行链式操作,p3=p2=p1
	person& operator=(person &p) {
		if (num != NULL) {
			delete num;
			num = NULL;
		}
		num = new int(*p.num);
		return *this;
	}
};

ostream& operator<<(ostream &cout, const person& p) {
	cout << *p.num;
	return cout;
}

void main() {
	person p1(10);
	person p2(12);
						
	p2=p1;//因为等于号已经重载了,所以析构的时候不会出现内粗你重复释放的问题				 
	cout << p1 << endl;
	cout << p2 << endl;
}

关系运算符重载

#include <iostream>
using namespace std;

class person {
	friend ostream& operator<<(ostream& cout, const person& p);
private: 
	int *num;
public:
	person(int num){
		this->num = new int(num);
	}
	~person() {
		if (this->num != NULL)
			delete(this->num);
	}
	//关系运算符重载
	bool operator==(person &p) {
		if(*this->num == *p.num)
			return true;
		return false;
	}
};

ostream& operator<<(ostream &cout, const person& p) {
	cout << *p.num;
	return cout;
}

void main() {
	person p1(10);
	person p2(12);
	if (p2 == p1)//前面不写==运算符则这里会报错
		cout<<"p2等于p1"<<endl;
	else
		cout << "p2不等于p1" << endl;

}

函数调用运算符重载

函数调用运算符()也可以重载
由于重载后的使用方式和函数非常相似所以成为仿函数

#include <iostream>
#include <string>
using namespace std;

class person {
public:
	void operator()(string test) {//函数调用运算符重载
		cout << test << endl;
	}
};
void main() {
	person p;
	p("hello world");//等价于p.operator()("hello world")
}

也可以进行匿名类的调用

函数调用运算符重载
函数调用运算符()也可以重载
由于重载后的使用方式和函数非常相似所以成为仿函数

#include <iostream>
#include <string>
using namespace std;

class person {
public:
	void operator()(string test) {//函数调用运算符重载
		cout << test << endl;
	}
};
void main() {
	person()("hello world");//这样就无需创建一个实例,用完系统立即回收
}

总结:运算符重载的用处非常多,而且也便于阅读和编程,是一个很实用的技能。
注意:编程的时候要做好注释,否则容易出现忘记重载的参数是什么的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值