智能指针

智能指针

1.为什么引入智能指针?

一个程序中可能因为各种情况导致内存泄漏问题,但是内存泄漏在一开始发生时并不是很容易被我们所发现,那我们先来看看内存泄漏的场景:

//1.执行流跳转导致没来得及释放

void test()
{
int *p = (int*)malloc(100);
//...
//...
return;   //在遇到return , break, goto,continue等语句的时候,就会引发执行流跳转
free(p);
}

假如我们在程序开头部分new了一个变量或其他,那么与它配套使用的delete就应该出现在它的下一句,但是可能在他们两中间要有一些条件执行,这些条件中的某些语句可能引发程序结束或退出,那么后面的delete语句则不会被执行,也就是说我们前面申请的空间没有还给系统,这样就会导致内存的泄漏。

2.释放多次带来的安全问题
void func1()
{
   //....
   throw;
  //....
}
void test()
{
    int* p1 = (int*)malloc(100);
    try
    {
        func();
    }
    catch(...)
    {
        delete p1;
        throw;
    }
    delete p1;
}   

2.智能指针的使用及原理

2.1RAII

RAII(Resource Acquisition Is Initialization -> 资源获得即初始化),是一种利用对象生命周期来控制程序资源的简单技术。在对象构造时获得资源,接着控制对资源的访问在对象的生命周期内始终有效,最后在对象析构时释放资源。这样的好处在于:

  • 不需要显示的释放资源
  • 对象所管理的资源在其生命周期内始终有效
2.2智能指针的原理

// 使用RAII思想设计的SmartPtr类
template<class T>
class SmartPtr {
public:
   SmartPtr(T* ptr = nullptr)
   	: _ptr(ptr)
   {} 
   
   T& operator*()//重载*模仿普通指针的行为
   {
   	return *_ptr;
   }
   
   T* operator->()//如果我们的初始化了结构体指针,我们还需要用重载->来访问他的成员
   {
   	return _ptr;
   }

   ~SmartPtr()
   {
   	if (_ptr)
   		delete _ptr;
   }
private:
   T* _ptr;
};

int main()
{
   int* p = new int;
   SmartPtr<int> sp(p);
   *sp = 10;
   cout << *sp << endl;
   
   system("pause");
   return 0;
}

总结一下智能指针的特性:

  • RAII特性
  • 重载operator*和opertaor->,具有像指针一样的行为。

3.C++中的智能指针

3.1智能指针的发展史

在这里插入图片描述

3.2auto_ptr
3.2.1auto_ptr的设计思路

成员函数有_ptr和_ower,构造函数时最开始就将对象的_owner赋为true,在拷贝构造或赋值操作后,将_owner改为false,这就实现了管理权的转移,使一块空间只能有一个管理员。析构时,只有_owner为true才有资格释放空间。这个做法会造成野指针的问题。下图会做解释。最好不要使用auto_ptr。

3.2.2auto_ptr模拟实现1.0
template<class T>
class AutoPtr
	 {
public:
  AutoPtr(T* ptr = NULL)
	   :_ptr(ptr)
	  , _owner(true)
         {}
	 
  AutoPtr(AutoPtr<T>& ap)
	  :_ptr(ap._ptr)
	  , _owner(ap._owner)
       {
	 	 ap._owner = false;//ap的管理权到了this的手上,实现了管理权转移   
       }
	 
  AutoPtr<T>& operator&
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值