C++之智能指针std::shared_ptr简单使用和理解

1  智能指针std::shared_ptr相关知识和如何使用
我们这里先说下智能指针std::shared_ptr,因为我看到我我们项目c++代码里面用得很多,我不是不会,所以记录学习下

先让ubuntu终端支持c++11,如果自己的电脑还没配置号,可以先看下我的这篇博客linux之让终端支持C++11/14编译cpp文件

 

1)  所在的头文件

#include <memory>
 

2)  介绍:

     shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting),比如我们把只能指针赋值给另外一个对象,那么对象多了一个智能指针指向它,所以这个时候引用计数会增加一个,我们可以用shared_ptr.use_count()函数查看这个智能指针的引用计数,一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除,当我们程序结束进行return的时候,智能指针的引用计数会减1,不知道我理解有没有问题.有的话请老铁们指出.

 

3)  share_ptr的三种初始化方法
     1.通过一个指向堆上申请的空间的指针初始化(切记不要用栈上的指针,否则,当智能指针全部释放控制权(栈中的对象离开作用域本身就会析构一次),将会析构对象,导致出错)

     比如如下

     int a = new int(100);
 
     std::shared_ptr ptr(a); //我们不能写成std::shared_ptr ptr = a;这样写错误,不行你编译运行看下,编译不过
 

     2.  通过make_shared函数得到

std::shared_ptr<int> ptr1 = std::make_shared<int>(15);
     3 拷贝初始化

    std::shared_ptr<int> ptr2(ptr1);
    //std::shared_ptr<int> ptr2 = ptr1;这样赋值是错误的,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr2(ptr1);
 

4)  reset函数

    当只能指针调用了reset函数的时候,就不会再指向这个对象了,所以如果还有其它智能指针指向这个对象,那么另外一个智能指针的use_count()函数结果会减1

 

5)  智能指针的enable_shared_from_this和shared_from_this

为什么要用到enable_shared_from_this和shared_from_this,比如我们写一个普通的类,有析构函数,一个智能指针指向类对象的时候,我们析构函数会析购一次,然后智能指针会析构一次,析构两次就有问题,如下写法

Student{
    Student(){}
    ~Student()
    {
        std::cout << "~Student被调用" << std::endl;    
    }
    std::shared_ptr<Student> getStudent()
    {
        return std::shared_ptr<Student>(this);    
    } 
};
所以我们一般用这个类继续enable_shared_from_this<Student>,然后getStudent函数的时候返回shared_from_this()这个就行

 

6 ) 如何判断智能指针是否为null,我么可以使用get()函数,比如

std::shared_ptr<int> ptr(new int(100));
if (ptr.get()) {
    std::cout << "ptr is not null" << std::endl;
} else {
    std::cout << "ptr is null" << std::enel;
}
 

 
 
 
 
2  测试Demo
#include <iostream>
#include <memory>
 
 
using namespace std;
 
class Student : public enable_shared_from_this<Student>
{
public:
        Student() {}
    ~Student()
    {
        std::cout << "~Student被调用" << std::endl;    
    }
    std::shared_ptr<Student> getStudent()
    {
        return shared_from_this();    
    } 
    std::string name;
    void setName(std::string name);
    std::string getName();
};
 
void Student::setName(std::string name)
{
    this->name = name;    
}
 
std::string Student::getName()
{
    return name;    
}
 
int main()
{
    int *p = new int(10);    
    //std::shared_ptr<int> ptr = p;这样赋值是错误的额,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr(p);
    std::shared_ptr<int> ptr(p);
    std::shared_ptr<int> ptr1 = std::make_shared<int>(15);
    std::shared_ptr<int> ptr2(ptr1);
    //std::shared_ptr<int> ptr2 = ptr1;这样赋值是错误的,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr2(ptr1);
    std::cout << "ptr.use_count() is:" << ptr.use_count() << "  *ptr is:" << *ptr << std::endl;
    std::cout << "ptr1.use_count() is:" << ptr1.use_count() << "  *ptr1 is:" << *ptr1 << std::endl;
    std::cout << "ptr2.use_count() is:" << ptr2.use_count() << "  *ptr2 is:" << *ptr2 << std::endl;
    
    ptr2.reset();
    //这是时候ptr2已经销毁,指向的对象引用计数会减1,这个指针的不再指向任何对象,所以我们不能使用*ptr2了,下面一行代码使用肯定会报错,我先注释掉
    //std::cout << "ptr2.use_count() is:" << ptr2.use_count() << "*ptr2 is:" << *ptr2 << std::endl;
        std::cout << "ptr1.use_count() is:" << ptr1.use_count() << "   *ptr1 is:" << *ptr1 << std::endl;
    Student *stu = new Student();
    std::shared_ptr<Student> ptr_stu(stu);
    std::string name = "chenyu";
    ptr_stu->setName(name);
    std::string result = ptr_stu->getName();
        std::cout << "ptr_stu.use_count() is:" << ptr_stu.use_count() << std::endl;
    std::cout << "my name is:" << result << std::endl;
        return 0;
}
 

 

 

 

3  运行结果以及分析
ptr.use_count() is:1  *ptr is:10
ptr1.use_count() is:2  *ptr1 is:15
ptr2.use_count() is:2  *ptr2 is:15
ptr1.use_count() is:1   *ptr1 is:15
ptr_stu.use_count() is:1
my name is:chenyu
~Student被调用
很明显调用了reset之后,引用技术减1了,然后程序在return的时候,ptr和ptr1和ptr_stu的引用计数会变为0,所以指向的对象就会自动销毁,所以不会导致内存泄漏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flybirding10011

谢谢支持啊999

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值