标签搜索

目 录CONTENT

文章目录

C++中各种智能指针的实现及弊端(二).md

小小城
2021-08-22 / 0 评论 / 0 点赞 / 13 阅读 / 1,367 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-05-02,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

C++中各种智能指针的实现及弊端(二)

@[toc]

一:实现auto_ptr

C ++98版本的库中提供了auto_ptr的智能指针:
auto_ptr文档

// C++库中的智能指针都定义在memory这个头文件中
#include <memory>
class Date
{
public:
	Date() { cout << "Date()" << endl;}
	~Date(){ cout << "~Date()" << endl;}
	int _year;
	int _month;
	int _day;
};

int main()
{
	auto_ptr<Date> ap(new Date);
	auto_ptr<Date> copy(ap);
	// auto_ptr的问题:当对象拷贝或者赋值后,前面的对象就悬空了
	// C++98中设计的auto_ptr问题是非常明显的,所以实际中很多公司明确规定了不能使用	auto_ptr
	ap->_year = 2018;
	return 0;
}
  •  auto_ptr的实现原理:管理权转移的思想,下面简化模拟实现了一份AutoPtr来了解它的原理
// 模拟实现一份简答的AutoPtr,了解原理
template<class T>
class AutoPtr
{
public:
	AutoPtr(T* ptr = NULL)
	: _ptr(ptr)
	{}
	~AutoPtr()
	{
		if(_ptr)
			delete _ptr;
	}
	// 一旦发生拷贝,就将ap中资源转移到当前对象中,然后另ap与其所管理资源断开联系,
	// 这样就解决了一块空间被多个对象使用而造成程序奔溃问题
	AutoPtr(AutoPtr<T>& ap)
	: _ptr(ap._ptr)
	{
		ap._ptr = NULL;
	}
	AutoPtr<T>& operator=(AutoPtr<T>& ap)
	{
		// 检测是否为自己给自己赋值
		if(this != &ap)
		{
			// 释放当前对象中资源
			if(_ptr)
				delete _ptr;
			// 转移ap中资源到当前对象中
			_ptr = ap._ptr;
			ap._ptr = NULL;
		}
		return *this;
	}

	T& operator*() {return *_ptr;}
	T* operator->() { return _ptr;}
private:
	T* _ptr;
};

int main()
{
	AutoPtr<Date> ap(new Date);
	// 现在再从实现原理层来分析会发现,这里拷贝后把ap对象的指针赋空了,导致ap对象悬空
	// 通过ap对象访问资源时就会出现问题。
	AutoPtr<Date> copy(ap);
	ap->_year = 2018;
	return 0;
}

二、auto_ptr的问题及解决办法

原理:
在这里插入图片描述

  • 缺陷:一旦发生拷贝后,就只能有一个对象可以操纵他们所管理的资源,因为原对象已经断开和资源的链接
  • 解决办法:可以引入一个变量控制资源的释放权,即不断开就对象和资源的联系,发生拷贝时,让就对象无法获得资源释放权即可,具体代码自己实现,这个比较简单,加一个bool类型的成员变量即可

但是采用上面的解决方法仍然有缺陷:

  • 可能会造成野指针问
0

评论区