C++——运算符重载

1、运算符重载的概念

  1. 运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
  2. 运算符重载的目的是让语法更加简洁
  3. 运算符重载不能改变本来寓意,不能改变基础类型寓意
  4. 运算符重载的本质是另一种函数调用(是编译器去调用)
  5. 这个函数统一的名字叫operator
  6. 重载函数可以写成全局或成员函数
  7. 重载函数如果写成全局的,那么双目运算符左边的是第一个参数,右边是第二个参数
  8. 重载函数如果写成成员函数,那么双目运算符的左边是this,右边是第一个参数
  9. 不能改变运算符优先级,不能改变运算符的参数个数。

2、加号运算符重载

1、同类型的对象相加

#include 
using namespace std;

class Maker
{
public:
	Maker(int id, int age)
	{
		this->id = id;
		this->age = age;
	}
	//写成成员函数,那么只需要一个参数,这个参数是加号的右边
	Maker operator+(Maker& m2)
	{
		Maker temp(this->id + m2.id, this->age + m2.age);
		return temp;
	}
public:
	int id;
	int age;
};
//重载加号运算符  全局函数方式
//Maker operator+(Maker &p1,Maker &p2)
//{
//	Maker temp(p1.id + p2.id, p1.age + p2.age);
//	return temp;
//}
void test()
{
	Maker m1(1, 10);
	Maker m2(2, 20);

	Maker m3 = m1 + m2;
	cout << m3.id << endl;
	cout << m3.age << endl;
}
int main()
{
	test();
	return 0;
}

2、不同对象类型相加

#include 
using namespace std;

class Maker
{
public:
	Maker(int id, int age)
	{
		this->id = id;
		this->age = age;
	}
	//写成成员函数,那么只需要一个参数,这个参数是加号的右边
	Maker operator+(Maker& m2)
	{
		Maker temp(this->id + m2.id, this->age + m2.age);
		return temp;
	}
public:
	int id;
	int age;
};

class Student
{
public:
	Student() {
		mid = 0;
	}
	Student(int id) {
		mid = id;
	}
public:
	int mid;
};

Maker operator+(Maker& m1, Student& s1)
{
	Maker temp(m1.id + s1.mid, 20);
	return temp;
}
Student operator+(Student& s1, Maker& m1)
{
	Student temp(s1.mid + m1.id);
	return temp;
}
void test()
{
	Maker m1(1, 10);
	Student s1(2);
	Maker m3 = m1 + s1;
	cout << m3.id << endl;
	
	Student s2 = s1 + m1;
	cout << s2.mid<<endl;
}
int main()
{
	test();
	return 0;
}

3、减号运算符重载

#include 
using namespace std;

class Maker
{
public:
	Maker(int id, int age)
	{
		this->id = id;
		this->age = age;
	}
	//写成成员函数,那么只需要一个参数,这个参数是加号的右边
	Maker operator-(Maker& m2)
	{
		Maker temp(this->id - m2.id, this->age - m2.age);
		return temp;
	}
public:
	int id;
	int age;
};
void test()
{
	Maker m1(10, 18);
	Maker m2(5, 15);

	Maker m3 = m1 - m2;
	cout << m3.id << endl;
	cout << m3.age << endl;
}
int main()
{
	test();
	return 0;
}

4、左移运算符重载

#include 
#include 
using namespace std;

class Maker
{
public:
	Maker(int id, string name)
	{
		this->id = id;
		this->name = name;
	}
public:
	int id;
	string name;
};
//1、形参和实参是一个对象
//2、不能改变库类中的代码
//3、ostream中把拷贝构造函数私有化了
//4、如果要和endl一起使用,那么必须返回ostream的对象
ostream& operator<<(ostream& out, Maker& m1)
{
	cout << m1.id << " " << m1.name << endl;
	return out;
}
void test()
{
	Maker m1(10, "薯片");
	cout << m1 << endl;
}
int main()
{
	test();
	return 0;
}

5、右移运算符

#include 
#include 
using namespace std;

class Maker
{
public:
	Maker(int id, string name)
	{
		this->id = id;
		this->name = name;
	}
	int getAge() {
		return this->id;
	}
public:
	int id;
	string name;
};

istream &operator>>(istream& in, Maker& m1)
{
	cin >> m1.id;
	cin >> m1.name;
	return in;
}
void test()
{
	Maker m(10, "薯片");
	cin >> m;
	cout << m.getAge() << endl;
}
int main()
{
	test();
	return 0;
}

6、关系运算符重载

#include 
#include 
using namespace std;

class Maker
{
public:
	Maker() {};
	Maker(int id)
	{
		this->id = id;
	}
	bool operator==(Maker &m) {
		if (this->id == m.id) {
			return true;
		}
		return false;
	}
	bool operator!=(Maker& m) {
		if (this->id != m.id) {
			return true;
		}
		return false;
	}
public:
	int id;
};

void test()
{
	Maker m1(10);
	Maker m;
	if (m1 == m) {
		cout << "真" << endl;
	}
	else {
		cout << "假" << endl;
	}

	if (m1 != m) {
		cout << "真" << endl;
	}
	else {
		cout << "假" << endl;
	}
	
}
int main()
{
	test();
	return 0;
}

7、前置加加和后置加加

#include 
#include 
using namespace std;

class Maker
{
	friend ostream& operator<<(ostream& os, Maker& m);
public:
	Maker(int id)
	{
		this->id = id;
	}
	//重置前置加加
	Maker& operator++()
	{
		++this->id;
		return *this;
	}
	//重置后置加加
	Maker operator++(int)//占位参数,必须是int
	{
		Maker tmp(*this);//tmp是局部变量,局部变量不能以引用返回
		++this->id;
		return tmp;
	}
private:
	int id;
};

ostream& operator<<(ostream& out, Maker& m) {
	cout << m.id << endl;
	return out;
}

void test()
{
	Maker m1(10);
	cout << ++m1;
	cout << m1++;
	
	
}
int main()
{
	test();
	return 0;
}

8、智能指针类

8.1、智能指针类是管理另一个类的对象的释放

#include 
#include 
using namespace std;

class Maker
{
public:
	Maker() {
		cout << "Maker的无参构造" << endl;
	}
	~Maker() {
		cout << "Maker的析构函数" << endl;
	}

};

//智能指针类
class SmartPoint
{
public:
	SmartPoint(Maker* p)
	{
		this->pMaker = p;
	}
	~SmartPoint()
	{
		cout << "SmartPoint的析构函数" << endl;
		if (this->pMaker != NULL)
		{
			delete this->pMaker;
			this->pMaker == NULL;
		}

	}
private:
	Maker* pMaker;
};
void test()
{
	Maker* p = new Maker;//在堆区开辟的数据,需要手动delete掉

	SmartPoint sm(p);//栈区  会调用析构函数
	//当test()函数结束时,会调用smartPoint的析构函数。
	//在这析构函数中delete了Marker的对象,会调用Maker的析构函数
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

8.2、指针运算符重载

#include 
#include 
using namespace std;

class Maker
{
public:
	Maker() {
		cout << "Maker的无参构造" << endl;
	}
	void printMaker()
	{
		cout << "Hello Maker" << endl;
	}
	~Maker() {
		cout << "Maker的析构函数" << endl;
	}

};

//智能指针类
class SmartPoint
{
public:
	SmartPoint(Maker* p)
	{
		this->pMaker = p;
	}
	//重载指针运算符
	Maker* operator->()
	{
		return this->pMaker;
	}
	~SmartPoint()
	{
		cout << "SmartPoint的析构函数" << endl;
		if (this->pMaker != NULL)
		{
			delete this->pMaker;
			this->pMaker == NULL;
		}

	}
private:
	Maker* pMaker;
};
void test()
{
	Maker* p = new Maker;

	SmartPoint sm(p);
	
	sm->printMaker();
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

8.3、重载星号

	//重载星号
	Maker& operator*()
	{
		return *pMaker;
	}

void test()
{
	Maker* p = new Maker;

	SmartPoint sm(p);
	(*sm).printMaker();
}

9、重载函数调用符号

9.1、类里有重载函数调用符号的类实例化的对象也叫仿函数

#include 
#include 
using namespace std;

//一个类如果重载了函数调用符号,那么这个类实例化出的对象也叫仿函数
//仿函数的作用:1、方便代码维护
class Maker
{
public:
	Maker(string name) 
	{
		this->m_Name = name;
	};
	void printMaker()
	{
		cout << "hello " <<this->m_Name<< endl;
	}
	//重载()
	void operator()()
	{
		cout << "hello" << endl;
	}
public:
	string m_Name;
};


void test()
{
	Maker func("薯片");
	func();//看着像函数,但func是对象

}
int main()
{
	test();
	return 0;
}

你可能感兴趣的:(c++,算法,数据结构)