C++ 的智能指针std::shared_ptr

1、为什么需要智能指针

智能指针是为了解决内存泄漏问题

内存泄漏问题,本质上是因为程序员自己忘记主动释放导致的

智能指针的解决思路是:连带自动释放

2、智能指针的本质工作原理

(1)一方面,利用局部变量/对象分配在栈上,代码段结束时会自动释放的特性
(2)另一方面,利用对象释放时会自动调用析构函数的特性

3.智能指针的使用实例

使用代码如下:

# include<iostream>
#include <memory>
using namespace std;
 class Ball
{
        public: Ball()
        {
            cout<<"A ball appears."<< endl;
        }

        ~Ball()
        {
            cout<<"A ball disappears."<< endl; 
        }
        void Bounce()
        {
            cout<<"A ball jumps."<<endl;
        }
};
int main()
{
//创建共享p指针指向Ball
 shared_ptr <Ball> p=make_shared<Ball>(); 
 //输出p共享指针的使用次数
 cout<<p. use_count()<< endl; 
 //创建共享p2指针指向Ball
 shared_ptr <Ball>p2=p;
 //输出p,p2共享指针的使用次数
 cout<<p. use_count()<<""<<p2. use_count()<< endl; 
 //创建共享p3指针指向Ball
 shared_ptr <Ball>p3=p;
 //输出p,p2,p3共享指针的使用次数
 cout <<p. use_count()<<""<<p2. use_count()<<p3. use_count()<<endl;
 //释放P
 p. reset();
 //释放P2
 p2. reset();
 //释放P3
 p3. reset();
}

 运行以上代码后实际的运行结果如下:

在实际使用时,将后面的三句指令屏蔽后也是相同的的效果。

# include<iostream>
#include <memory>
using namespace std;
 class Ball
{
        public: Ball()
        {
            cout<<"A ball appears."<< endl;
        }

        ~Ball()
        {
            cout<<"A ball disappears."<< endl; 
        }
        void Bounce()
        {
            cout<<"A ball jumps."<<endl;
        }
};
int main()
{
//创建共享p指针指向Ball
 shared_ptr <Ball> p=make_shared<Ball>(); 
 //输出p共享指针的使用次数
 cout<<p. use_count()<< endl; 
 //创建共享p2指针指向Ball
 shared_ptr <Ball>p2=p;
 //输出p,p2共享指针的使用次数
 cout<<p. use_count()<<""<<p2. use_count()<< endl; 
 //创建共享p3指针指向Ball
 shared_ptr <Ball>p3=p;
 //输出p,p2,p3共享指针的使用次数
 cout <<p. use_count()<<""<<p2. use_count()<<p3. use_count()<<endl;
 //释放P
 //p. reset();
 //释放P2
 //p2. reset();
 //释放P3
 //p3. reset();
}

  运行以上代码后实际的运行结果如下:

在实际使用时以上代码中的.reset()函数,可以在该函数(方法)中添加新的成员变量,使智能指针指向一个新的同类的地址,代码如下。

# include<iostream>
#include <memory>
using namespace std;
/*************测试使用Ball******************/
 class Ball
{
        public: Ball()
        {
            cout<<"A ball appears."<< endl;
        }

        ~Ball()
        {
            cout<<"A ball disappears."<< endl; 
        }
        void Bounce()
        {
            cout<<"A ball jumps."<<endl;
        }
};

/*************测试使用Ball2******************/
 class Ball2
{
        public: Ball2()
        {
            cout<<"A ball2 appears."<< endl;
        }

        ~Ball2()
        {
            cout<<"A ball2 disappears."<< endl; 
        }
        void Bounce2()
        {
            cout<<"A ball2 jumps."<<endl;
        }
};


int main()
{
//创建共享p指针指向Ball
 shared_ptr <Ball> p=make_shared<Ball>(); 
 //输出p共享指针的使用次数
 cout<<p. use_count()<< endl; 
 //创建共享p2指针指向Ball
 shared_ptr <Ball>p2=p;
 //输出p,p2共享指针的使用次数
  cout<<p. use_count()<<""<<p2. use_count()<< endl; 
   //创建共享p3指针指向Ball
 shared_ptr <Ball>p3=p;
 //输出p,p2,p3共享指针的使用次数
 cout <<p. use_count()<<""<<p2. use_count()<<p3. use_count()<<endl;
 p. reset(new Ball);
// p2. reset();
// p3. reset();
}

运行结果:

运行了两次析构,说明我们释放了两个Ball类的内存。

在实际使用时可以考虑我们是否可以指向别的类,比如上面的Ball2,实际是不行的,在我们定义智能指针时,它的数据类型就已经被确定了,我们不能再修改它的数据类型了。

 

4.使用时注意事项

在使用时当我们使用裸指针和智能指针指向同一个地址时,当我们将智能指针都删除后,裸指针所指向的内存也不复存在,但裸指针还存在,这时再次调用裸指针有可能发生不可预料的后果。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值