C++的运算符重载,浅显易懂

C++预定义中的运算符只能对基本的内置数据类型进行操作,但是对于我们自定义的类型是没有办法操作的,我们对这么运算符重新定义,才能对我们自己定义的数据类型进行操作。

对于运算符重载,它的实质其实是函数重载或者说,函数多态。重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。运算符重载函数的格式:

<返回类型说明符> operator <运算符符号>(<参数表>) { <函数体> }

+ 运算符重载

+号运算符重载的作用就是实现两个自定义数据类型相加的运算

#include <iostream>
#include <string>

using namespace std;

class Student
{
public:
	Student() {}
	Student(int a, int b)
	{
		m_A = a;
		m_B = b;
	}
	Student operator+(const Student &s)
	{
		Student temp;
		temp.m_A = this->m_A + s.m_A;
		temp.m_B = this->m_B + s.m_B;
		return temp;
	}

public:
	int m_A;
	int m_B;
};
//全局函数实现 + 号运算符重载
//Student operator+(const Student &s1, const Student &s2)
//{
//	Student temp;
//	temp.m_A = s1.m_A + s2.m_A;
//	temp.m_B = s1.m_B + s2.m_B;
//	return temp;
//}

void test01()
{
	Student s1(10, 10);
	Student s2(20, 20);

	Student s3 = s1 + s2;
	cout << "m_A = " << s3.m_A << "\nm_B = " << s3.m_B << endl;
}
int main()
{
	test01();

	system("pause");
	return 0;
}

<< 左移运算符重载

我们之前是这样使用左移运算符的
int a = 10;
cout << a;
现在我们有一个叫s的Student的类,类当中有年龄,班级,我们想这样使用cout
cout << s
就可以直接将类当中的学号,年龄,班级全部输出。

class Student
{
	friend ostream& operator<<(ostream& cout, Student& s);

public:

	Student(int id, int age, int Class)
	{
		this->m_Id = id;
		this->m_Age = age;
		this->m_Class = Class;
	}

	//成员函数 实现不了
	//void operator<<(Person& p){
	//}

private:
	int m_Id;
	int m_Age;
	int m_Class;
};

//全局函数实现左移重载
//cout的类型为ostream,对象只能有一个
//返回cout的目的是为了链式编程,所以这里的返回类型我们是ostream而且是以引用方式
//当然也可以是void,但是如果返回的是void,那么下面的cout << s之后就不能追加后面的"hello!",
//因为返回的是void,而想要追加内容,我们返回的必须是cout才行。
ostream& operator<<(ostream& cout, Student& s) {
	cout << "id:" << s.m_Id << " age:" << s.m_Age << "class:" << s.m_Class;
	return cout;
}

void test01() {

	Student s(001, 10, 2020001);

	cout << s << "hello!" << endl; //链式编程
}

int main() {

	test01();

	system("pause");

	return 0;
}

++(–)运算符重载

作用是可以输出自定义数据类型
下面代码展示的是++运算符重载,当然–也是同理

class Integer
{
	//我们先要重载一下左移运算符
	friend ostream& operator<<(ostream& out, MyInteger myint);
	
public:
	Integer() {
		m_Num = 0;
	}
	//前置++	先++	再返回
	Integer& operator++() {

		m_Num++;
		
		return *this;
	}
	
	//后置++	先返回	再++
	Integer operator++(int) {

		Integer temp = *this; //记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;
		m_Num++;
		return temp;
	}
	
private:
	int m_Num;
};

ostream& operator<<(ostream& out, Integer myint) {
	out << myint.m_Num;
	return out;
}

//前置++ 先++ 再返回
void test01() {
	Integer myInt;
	cout << ++myInt << endl;
	cout << myInt << endl;
}

//后置++ 先返回 再++
void test02() {

	Integer myInt;
	cout << myInt++ << endl;
	cout << myInt << endl;
}

int main() {

	test01();
	test02();

	system("pause");

	return 0;
}

==运算符重载

让两个自定义类型进行比较

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	};

	bool operator==(Person & p)
	{
		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {
			return true;
		} else {
			return false;
		}
	}

	bool operator!=(Person & p)
	{
		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {
			return false;
		} else {
			return true;
		}
	}

	string m_Name;
	int m_Age;
};

void test01()
{
	//int a = 0;
	//int b = 0;

	Person p1("张三", 18);
	Person p2("张三", 18);

	if (p1 == p2) {
		cout << "p1和p2相等" << endl;
	} else {
		cout << "p1和p2不相等" << endl;
	}

	if (p1 != p2)
	{
		cout << "a和b不相等" << endl;
	} else {
		cout << "p1和p2相等" << endl;
	}
}


int main() {

	test01();

	system("pause");

	return 0;
}

函数调用运算符重载

函数调用运算符()也可以重载,由于其长得很像函数,故称之为仿函数

class MyAdd
{
public:
	int operator()(int a, int b)
	{
		return a + b;
	}
};

void test01()
{
	MyAdd add;
	int ret = add(10, 10);
	cout << "ret = " << ret << endl;

	//匿名对象调用  
	cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;
}

int main() {

	test02();

	system("pause");
	return 0;
}

赋值运算符重载

我们知道,编辑器会给一个类至少添加4个函数,分别是

  • 默认无参构造函数
  • 默认析构函数
  • 默认拷贝构造函数
  • 赋值运算符 operator=

若类中有属性指向堆区,做赋值操作时会出现深浅拷贝问题

class Person
{
public:

	Person(int age)
	{
		//将年龄数据开辟到堆区
		m_Age = new int(age);
	}

	//重载赋值运算符 
	Person& operator=(Person &p)
	{
		if (m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
		//编译器提供的代码是浅拷贝
		//提供深拷贝重新new一块区域来操作m_Age 解决浅拷贝的问题
		m_Age = new int(*p.m_Age);

		//返回自身
		return *this;
	}

	~Person()
	{
		if (m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
	}

	int *m_Age;

};


void test01()
{
	Person p1(18);
	Person p2(20);
	Person p3(30);

	p3 = p2 = p1; //赋值

	cout << "p1的年龄为:" << *p1.m_Age << endl;
	cout << "p2的年龄为:" << *p2.m_Age << endl;
	cout << "p3的年龄为:" << *p3.m_Age << endl;
}

int main() 
{
	test01();
	
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值