2022-06-24

本文详细介绍了C++中复制运算符、关系运算符和函数调用运算符的重载。通过实例展示了如何处理深浅拷贝问题,以避免指针悬空。同时,解释了如何重载‘==’运算符以比较对象的相等性,并演示了函数调用运算符重载,将其用于实现类似函数调用的行为,增强代码的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要内容
1.复制运算符重载。
2.重载关系运算符,实现两个自定义的类型对象进行对比操作。
3.函数调用运算符重载。
一.复制运算符重载
C++编译过程中,会给一个类添加至少4个函数
1.默认的构造函数(无参,函数体为空)。
2.默认的析构函数(无参,函数体为空)。
3…默认的拷贝构造函数,对属性进行值拷贝(有属性指向堆栈区,会存在深浅拷贝的问题)。
(深浅拷贝是指:浅:简单的赋值拷贝操作。深:在堆区重新申请空间,进行拷贝操作,解决指针悬挂问题)
4.赋值运算符operator=,对属性进行浅拷贝。
编译器默认提供的为浅拷贝操作,如果涉及到堆区数据,会出现重复释放空间的问题导致程序崩溃。因此,此处的赋值重载,主要是考虑深拷贝的问题。
现以年龄赋值操作为例:
1.借助友元访问类的私有变量(见上一篇)
2.实现简单赋值操作–此时只需要用浅拷贝即可实现(见example1)
3.实现深拷贝操作。(见example2)
example1

#include <iostream>
using namespace std;

class Person
{
	friend ostream& operator<<(ostream& cout, Person p1);
public:

	
	
	Person(int m_age1) 
	{
		
		age1 = new int(m_age1);
	}

	//添加析构函数
	~Person()
	{
		if (age1 != NULL)
		{
			delete age1;
			age1 = NULL;
		}
	}
	

	int *age1;
};
void test()
{ 
	Person p1(30);
	Person p2(20);
	cout << "age1的年龄: " << *p1.age1 << endl;
	cout << "age2的年龄: " << *p2.age1 << endl;
	p1 = p2;
	cout << "age1的年龄: " << *p1.age1 << endl;
	cout << "age1的年龄: " << *p2.age1 << endl;

}
int main()
{
	test();
	system("pause");
	return 0;
}

不加析构函数:
在这里插入图片描述
添加析构函数~Person
在这里插入图片描述
程序可以实现正常运行,但是由于释放同一个堆区两个,造成指针悬空,程序异常退出。
example2
对赋值操作实现重载,其基本原理是实现深拷贝,即两个指针指向两个堆区,空间释放时,释放两块空间,避免指针悬空。
添加成员函数:

	Person operator=(Person &p) 
	{ 
		if (age1 != NULL)
		{
			delete age1;
			age1 = NULL;
		}
		age1 = new int(*p.age1);
		return *this;
	}

二.重载关系运算符
实现对==运算符的重载

#include <iostream>
using namespace std;

class Person 
{
public:
	 Person(string name, int age)
	{
		 m_age = age;
		 m_name = name;
	}

	bool operator==(Person & p) 
	{
		if (this->m_age == p.m_age && this->m_name == p.m_name)
		{
			//cout << "相同" << endl;
			return true;
		}
		else
		{
			//cout << "不相同" << endl;
			return false;
		}
	}
	string m_name;
	int  m_age;
};
void test01() 
{
	Person p1("ZARA1",18);
	Person p2("ZARA",18);

	if (p1 == p2) 
	{
		cout << " 相同 " << endl;
	}
	else
	{
		cout << " 不相同 " << endl;
	}
}
int main()
{
	test01();
	system("pause");
	return 0;
}

三.函数调用运算符重载
函数调用运算符()重载,重载之后的使用方式非常想函数的调用,一般也称之为仿函数。另:没有固定的写法,非常灵活

#include <iostream>
using namespace std;
class MyAdd 
{
public: 
	int operator()(int a,int b)
	{
		return a + b;
	}

};

int add(int a,int b)
{
	return a + b;
}

void test01() 
{
	MyAdd myAdd;
	int c = myAdd(10, 60);
	cout << "函数重置:" << c << endl;
	//匿名函数调用
	cout << "MyAdd()(10,60)=" << MyAdd()(10, 60) << endl;
}
void test02() 
{
	int d = add(10, 60);
	cout <<"正常函数调用:"<< d << endl;

}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值