智能指针

    我们在定义一个指针时,有可能没有写摧毁函数或语句;又或者你写了,但因为某种原因return返回掉了,而无法执行后面的语句,从而指针未释放,导致内存泄漏,这时我们就需要一个“智能指针”。无论程序代码出现什么语法错误,申请的指针都能释放掉。
    智能指针:1.不带引用计数的智能指针(auto_ptr, scoped_ptr, unique_ptr)
               2.带引用计数的智能指针(shared_ptr, weak_ptr)
     注:引用计数就是相当于一个资源管理计数器,每申请一个指针,就加加一下,这是属于一对一的情况,所以得用map来实现。map->first是存指针,map->second用来计数。库里的智能指针有addref增加资源的引用计数,delref减少资源的引用计数,getref获取资源的引用计数。

      简单的智能指针的实现:
        template<typename T>
        class M
       {
           public:
               M(T *ptr=NULL):mptr(ptr){};
               ~M()
               {
                   delete mptr; 
               }
           private:
                T *mptr;             
       }

       int main()
        {
               M<int> ptr1(new int());
        }
        此代码从main函数开始压栈,ptr调用构造函数,将ptr压栈,然后出栈,调用析构函数,析构对象,摧毁指针。这就利用栈帧的开辟和回退很巧妙的解决了指针有时无法释放的问题。而我们,平时直接ptr1=new M();在堆上申请内存,必须要手动删除(delete),我这个是栈帧的回退自动释放掉,所以这个指针一定是在栈上产生的。


智能指针的总结:
         1.智能指针解决的两个问题
           a.自动管理资源的释放,b.多线程访问共享的c++对象,产生线程安全问题(解决:定义对象时用强智能指针,其他一律用弱)
         2.带引用计数的智能指针是否是线程安全的?
           肯定不是线程安全的,引用计数有++,——的非原子操作;需要添加互斥锁;
         3.智能指针一定不能在堆上创建;
         4.智能指针的循环(交叉)引用问题?造成的问题?
           主要是强智能指针引起的,造成了资源泄露。
代码如下:
#include<iostream>
#include<memory>
class B;
class A
{
public:
	A(){cout<<"A()"<<endl;}
	~A(){cout<<"~A()"<<endl;}
         shared_ptr<B> _ptrb;
};
class B
{
public:
	B(){cout<<"B()"<<endl;}
	~B(){cout<<"~B()"<<endl;}
	shared_ptr<A> _ptra;
};

int main(int argc, char* argv[])
{
	
	shared_ptr<A> ptra(new A());
	shared_ptr<B> ptrb(new B());

	ptra->_ptrb = ptrb;
	ptrb->_ptra = ptra;
}

这是shared_ptr<A> ptra(new A());  shared_ptr<B> ptrb(new B())所表示的,栈上的两个对象分别指向堆上的两个指针;

这是后面两句表示强智能指针_ptrb, _ptra又分别指向了B,A;产生了循环交叉的问题。

分析:当ptra,ptrb分别指向A,B;这时增加资源计数器+1,+1;   当_ptrb, _ptra有分别指向B,A时,增加资源计数器+1+1,+1+1;

           代码执行完后,析构掉对象,计数-1;但计数器一共加了两次,不能归零,所以造成了资源的泄露。

解决:将_ptrb,_ptra定义成弱智能指针就行了;因为若只能指针只是观察引用计数并不会改变引用计数;所以只会+1.


注意:虽然弱智能指针能解决循环交叉的问题,但弱智能指针不能访问资源,需要提升shared_ptr<A> pa = _ptra.lock().

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值