运算符重载

128 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

1、什么是运算符重载?

我们知道函数重载,两个或多个函数的名字相同,但是因为他们的参数不同(数量、顺序或数据类型不同),编译器会把他们区分开来,再调用这些函数,并不会出现二义性。我的理解是运算也是一种函数,那么它也就能发生重载——运算符重载。

2、通过成员函数重载运算符

正常的加法运算符只能让两个实数进行相加,如果我们想要两个自定义数据类型的对象进行相加,就需要对加法“+”进行重载。

class Person
{
public:
	Person operator + (Person &p){
		Person temp;
		temp.m_a = this->m_a + p.m_a;
		temp.m_b = this->m_b + p.m_b;
		return temp;
	}
        //通过成员函数重载运算
	//运算符重载与可以发生函数重载
	Person operator+(int n){
		Person t;
		t.m_a = m_a + n;
		t.m_b = m_b + n;
		return t;
	}
	Person(int a,int b);
	Person() {}
	~Person();
	int m_a;
	int m_b;
};
Person::Person(int a,int b):m_a(a),m_b(b){
}
Person p1(1,2), p2(2,3);
Person::~Person(){
}
int main()
{
	Person p3 = p1 + p2;//此句的本质//Person p3 = p1.operator+(p2);
	cout << p3.m_a << ' ' << p3.m_b;
	int m = 10;
	Person p4 = p3 + 10;//加号重载函数
}

image.png

2、通过全局函数重载运算符

Person operator +(Person p1, Person p2){
	Person p3;
	p3.m_a = p1.m_a + p2.m_a;
	p3.m_b = p1.m_b + p2.m_b;
	return p3;
}
int main(){
	Person p3 = p1 + p2;//此句的本质//Person p3 = operator+(p1, p2);
	cout << p3.m_a << ' ' << p3.m_b;
	int m = 10;
	Person p4 = p3 + 10;//加号重载函数
}

image.png

3、左移运算符重载

// << 左移运算符重载 实现输出自定义类型
class Person
{
	friend void test01();//设置成友元,让他们可以访问私有成员
	friend ostream& operator<<(ostream &out, Person &p1);
public:

	/*void operator<<()
	{
		cout << p1.a << ' ' << p1.b << endl;
	}*/
//不能利用成员函数重载左移运算符 因为我们要的结果 是 cout<<p1形式使用成员函数无法实现,它实现的是p1<<cout形式。
private:
	int a;
	int b;
};
ostream& operator<<(ostream &out,Person &p1)
//把函数定义成ostream& 引用类型 是函数返回的依然是 输出类类cout,这样就可以实现链式输出。
//对比加法的全局函数重载,此函数可以实现cout<<p1 形式。
//ostream &cout 可以,out也可以,因为引用就是起别名
{
	out << p1.a << ' ' << p1.b << endl;
	return out;
}
void test01()
{
	Person p1;
	p1.a = 10;
	p1.b = 10;
	cout << p1 <<p1 <<"hello world!"<<endl;//链式输出
	cout << endl;
}
int main()
{
	test01();
}

image.png

4、“++”运算符重载

class Myint
{
   friend ostream& operator<<(ostream &cout, Myint main_int);
public:
   Myint() { m_a = 0; }//构造函数
   //重载前置++运算符
   Myint& operator++()//返回引用是为了对一个变量进行操作
   {
   	m_a++;
   	return *this;//
   }
   //重载后置++运算符
   Myint operator++(int)//占位参数,用于区分前置和后置
   {
   	Myint temp = *this;
   	m_a++;
   	return temp;//不能返回局部对象
   }
private:
   int m_a;
};
ostream& operator<<(ostream &cout, Myint main_int){
   cout << main_int.m_a;
   return cout;
}
void test01(){
   Myint main_int;
   cout << ++(++main_int) << endl;
   cout << main_int <<endl;
}
void test02(){
   Myint main_int;
   cout << main_int++ << endl;
   cout << main_int << endl;
}
int main(){
   //test01();
   test02();
}
//前置递增返回引用,后置递增返回值

image.png

5、注意事项

内置数据类型的表达式的运算符是不可能改变的。

不要滥用运算符重载。