C++基础11-类和对象之操作符重载2

本文深入探讨C++中的运算符重载技巧,包括等号操作符、new/delete操作符以及逻辑运算符的重载,并分析自定义智能指针的实现原理及其在资源自动管理中的应用。

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

总结:

1、等号操作符重载和拷贝构造函数重载一般用在数据成员中需要单独在堆区开辟内存时(指针)
2、new,delete重载内部还是使用malloc和free
3、逗号表达式(,)、或者(||),且(&&),条件表达式(?:)具有短路功能。
      但重载后失去此功能,故不建议重载这两个运算符
4、自定义智能指针auto_ptr(在c++11新特性中已经被移除)是一个模板类。
      可以自动被回收,自动释放

等号操作符重载:
 

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;


class Student {
public:
	Student() {
		this->id = 0;
		this->name = NULL;
	}
	Student(int id, char *name) {
		this->id = id;
		//this->name = name; 浅拷贝 错误
		this->name = new char[strlen(name) + 1];
		//this->name = name;  赋值错误
		strcpy(this->name, name);
	}
	Student(const Student& another) {
		this->id = another.id;
		//深拷贝
		this->name = new char[strlen(another.name) + 1];
		strcpy(this->name, another.name);
	}
	Student& operator=(const Student& another) {
		if (this == &another)  //防止自身赋值
			return *this;
		//先将自身的额外开辟的空间回收掉
		if (this->name != NULL) {
			delete this->name;
			this->name = NULL;
			this->id = 0;
		}
		//执行深拷贝
		this->id = another.id;
		this->name = new char[strlen(another.name) + 1]; 
		strcpy(this->name, another.name);
		return *this;
	}
	void printS() {
		cout << "id:"<<this->id << " name:" << this->name << endl;
	}
	~Student() {
		if (this->name != NULL) {
			delete this->name;
			this->name = NULL;
			this->id = 0;
		}
	}
private:
	int id;
	char *name;
};

void test01() {
	Student s1(1, "zhangdan");
	Student s2 = s1; //调用拷贝构造
	s2.printS();
	Student s3(2,"lisi");
	s2 = s1;  //赋值操作符 默认的赋值操作符为浅拷贝 只是简单的指针指向 
			  //两次析构 其中一次为空
	s2.printS();
}
/*
id:1 name:zhangdan
id:1 name:zhangdan
*/
int main()
{
	test01();
	return 0;
}
#endif

 new和delete操作符重载:

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

class A
{
public:
	A()
	{
		cout << "A()..." << endl;
	}
	A(int a) {
		cout << "A(int)..." << endl;
		this->a = a;
	}
	
	//重载的new操作符 依然会触发对象的构造函数
	void* operator new(size_t size) {
		cout << "重载new操作符" << endl;
		return malloc(size);
	}
	void* operator new[](size_t size) {
		cout << "重载new[]操作符" << endl;
		return malloc(size);
	}
	void operator delete(void *p) {
		cout << "重载了delete操作符" << endl;
		if (p != NULL) {
			free(p);
			p = NULL;
		}
	}
	void operator delete[](void *p) {
		cout << "重载了delete[]操作符" << endl;
		if (p != NULL) {
			free(p);
			p = NULL;
		}
	}
	~A() {
		cout << "~A().... " << endl;
	}

private:
	int a;
};
void test01() {
	int *value_p = new int;
	A *ap = new A(10);
	//等价于
	//ap->operator new(sizeof(A));
	delete ap;
}
/*
重载new操作符
A(int)...
~A()....
重载了delete操作符
*/
void test02() {
	int *array = (int *)malloc(sizeof(int) * 80);
	A *array_p = new A[5];
	//等价于
	//array_p->operator new[](sizeof(A[5]));
	delete[] array_p;
}
/*
重载new[]操作符
A()...
A()...
A()...
A()...
A()...
~A()....
~A()....
~A()....
~A()....
~A()....
重载了delete[]操作符
 */
int main(void)
{
	test01();
	cout << "test02" << endl;
	test02();

	return 0;
}
#endif

&&和||操作符重载(不建议使用,使用了短路功能):

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;


class Test
{
public:
	Test(int value) {
		this->value = value;
	}

	Test operator+(Test &another)
	{
		cout << "执行了+操作符重载" << endl;
		Test temp(this->value + another.value);
		return temp;
	}

	bool operator&&(Test &another)
	{
		cout << "执行了&&操作符重载" << endl;
		if (this->value && another.value) {
			return true;
		}
		else {
			return false;
		}

	}

	bool operator||(Test &another)
	{
		cout << "重载了||操作符" << endl;
		if (this->value || another.value) {
			return true;
		}
		else {
			return false;
		}
	}

	~Test() {
		cout << "~Test()..." << endl;
	}
private:
	int value;
};
void test01() {
	

	Test t1(0);
	Test t2(20);

	//重载&&操作符,并不会发生短路现象。

	if (t1 &&  t2) {	//t1.operator&&(t2)
		cout << "为真" << endl;
	}
	else {
		cout << "为假" << endl;
	}
}
/*
执行了&&操作符重载
为假
~Test()...
~Test()...
*/
void test02() {

	int a = 0;
	int b = 20;
	if (a && (a = 10)) {  //a为0的话,a+b 就不会执行  短路
		cout << "true" << endl;
	}
	cout << "a:" << a << endl;

	Test t1(0);
	Test t2(20);
	//重载&&操作符,并不会发生短路现象。
	if (t1 && (t1 + t2)) {	//t1.operator&&(t1.operator+(t2))
		cout << "为真" << endl;
	}
	else {
		cout << "为假" << endl;
	}
}
/*
a:0
执行了+操作符重载
~Test()...
执行了&&操作符重载
~Test()...
为假
~Test()...
~Test()...
*/
void test03() {
	Test t1(0);
	Test t2(20);
	//重载||操作符,并不会发生短路现象
	if (t1 || (t1 + t2)) {//t1.operator||(  t1.operator+(t2) )
		cout << "为真" << endl;
	}
	else {
		cout << "为假" << endl;
	}
}
/*
执行了+操作符重载
~Test()...
重载了||操作符
~Test()...
为真
~Test()...
~Test()...
*/
int main(void)
{
	int a = 1;
	int b = 20;
	test01();
	cout << "test02" << endl;
	test02();
	cout << "test03" << endl;
	test03();

	return 0;
}
#endif

自定义智能指针(stl中模板类,指针用完自动回收,不需要手动delete):

#if 1
#include<iostream>
using namespace std;
#include<memory>
//智能指针是自动被回收,自动释放
//只能指针是一个模板类
class A
{
public:
	A(int a)
	{
		cout << "A()..." << endl;
		this->a = a;
	}

	void func() {
		cout << "a = " << this->a << endl;
	}

	~A() {
		cout << "~A()..." << endl;
	}
private:
	int a;
};

void test01() {
	int *p = new int;
	*p = 20;
	delete p;
}
void test02() {
	//int *p = new int;
	//等价于
	auto_ptr<int> ptr(new int);
	*ptr = 100;
}
void test03() {
#if 0
	A* ap = new A(10);
	ap->func();
	(*ap).func();
	delete ap;
#endif
	//等价于
	auto_ptr<A> ap(new A(10));
	ap->func();
	(*ap).func();  //智能指针用完后 自动回收 调用析构函数
}
/*
A()...
a = 10
a = 10
~A()...
*/
class MyAutoPtr {
public:
	MyAutoPtr(A* ptr) {
		this->ptr = ptr; //ptr=new A(10)
	}
	~MyAutoPtr() {
		if (this->ptr != NULL) {
			cout << "delete ptr" << endl;
			delete ptr;
			ptr = NULL;
		}
	}
	A* operator->() {
		return this->ptr;
	}
	A& operator*()
	{
		return *ptr;  //*ptr表示返回对象本身
	}
private:
	A *ptr;  //内部指针
};
void test04() {
	MyAutoPtr myp(new A(10));
	myp->func();  //myp.ptr->func()
	(*myp).func();//*ptr.func()
}
/*
A()...
delete ptr
~A()...
*/
int main(void) {
	//test02();
	//test03();
	test04();
	return 0;
}
#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chde2Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值