C++|智能指针

目录

引入

一、智能指针的使用及原理

1.1RAII

1.2智能指针原理

1.3智能指针发展

1.3.1std::auto_ptr

1.3.2std::unique_ptr

1.3.3std::shared_ptr 

二、循环引用问题及解决方法

2.1循环引用

2.2解决方法 

三、删除器

四、C++11和boost中智能指针的关系 


引入

回顾上一篇章,学习了异常机制,但面临了一种情况还没有解决,就是异常带来的内存泄漏,如下:

#include <iostream>
using namespace std;


double Division(int a, int b)
{
	// 当b == 0时抛出异常
	if (b == 0)
		throw "Division by zero condition!";//抛出的异常是字符串
	else
		return ((double)a / (double)b);
}
void Func() 
{
    int* p = new int[1];
    int len, time;
    cin >> len >> time;

    cout << Division(len, time) << endl;

    delete[] p;

}

int main() {
    try 
    {
        Func();
    }
    catch (const char* errmsg) 
    {
        cout << "Caught in main: " << errmsg << endl;
    }
    return 0;
}

调用Division函数时,若抛出异常,最终是被main函数中的catch所捕获,直接进入到main函数中的catch中了,但是,delete[] p不会被执行了 ,导致的问题就是内存泄漏。那么可以通过智能指针来解决这个问题

一、智能指针的使用及原理

1.1RAII

RAII是一种利用对象生命周期来控制程序资源的简单技术。在对象构造时获取对象资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候由编译器顺带释放资源。实际上把控资源就是管理对象。

这种做法体现的优势是:

  • 不需要显示地释放资源
  • 采用这种方式,对象所需的资源在其生命期内始终保持有效

RAII是一种设计思想,而智能指针正是采用了这种思想。

RAII思想设计: 

#include <iostream>
using namespace std;

// 使用RAII思想设计的SmartPtr类
template<class T>
class SmartPtr {
public:
	SmartPtr(T* ptr = nullptr)
		:_ptr(ptr)
	{}

	~SmartPtr()
	{
		if (_ptr)
			delete _ptr;
	}

private:
	T* _ptr;
};
double Division(int a, int b)
{
	// 当b == 0时抛出异常
	if (b == 0)
		throw "Division by zero condition!";//抛出的异常是字符串
	else
		return ((double)a / (double)b);
}
void Func()
{
	int* p = new int[1];
	int len, time;
	cin >> len >> time;

	cout << Division(len, time) << endl;

	SmartPtr<int> sp(p);//当Division抛异常时,会被main函数中的catch捕获,那么程序会直接跳到main函数所在的catch
	//对此了,Func函数的栈帧会自动销毁,对于内置类型会自动释放,对于自定义类型而言会去调用它的析构函数
	//所以sp会去调用析构函数,同时释放了p的资源

}

int main() {
	try
	{
		Func();
	}
	catch (const char* errmsg)
	{
		cout << "Caught in main: " << errmsg << endl;
	}
	return 0;
}

输出结果:

1.2智能指针原理

上述的SmartPtr虽然是通过RAII思想设计的类,但还不能真正称作为智能指针,因为它还不有指针的行为。指针可以解引用,也可以通过->去访问所指空间的内容,因此还需要重载*和->。

#include <iostream>
using namespace std;
template<class T>
class SmartPtr {
public:
	SmartPtr(T* ptr = nullptr)
		: _ptr(ptr)
	{}
	~SmartPtr()
	{
		if (_ptr)
			delete _ptr;
	}

	T& operator*()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
private:
	T* _ptr;
};
struct Date
{
	int _year;
	int _month;
	int _day;
};
int main()
{
	SmartPtr<int> sp1(new int);
	*sp1 = 10;
	cout << *sp1 << endl;

	SmartPtr<Date> sparray(new Date);

	sparray->_year = 2024;
	sparray->_month = 7;
	sparray->_day = 7;

	cout << (*sparray)._year << ":" << (*sparray)._month << ":" << (*sparray)._day << endl;

	return 0;
}

输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值