C++智能指针使用指南 part2:智能指针本身的方法以及使用建议

往期文章

C++智能指针使用指南 part1:基本使用

智能指针本身的方法

智能指针有一个通用的规则,就是->表示用于调用指针原有的方法,而.则表示调用智能指针本身的方法。

对于unique_ptr

#include <iostream>
#include <vector>
#include <memory>
#include <assert.h>
using namespace std;
class A {
public:
    void do_something();
};
// 智能指针有一个通用的规则,就是`->`表示用于调用指针原有的方法,而`.`则表示调用智能指针本身的方法.
// 对于unique_ptr有下面几种本身方法
// get 获取智能指针保存的原生指针
// bool 判断该智能指针是否拥有指针
// release 释放所管理指针的所有权,返回原生指针,但是不销毁原生指针
// reset 释放并销毁原生指针。如果参数为一个新指针,将管理这个新指针
int main() {
    std::unique_ptr<A> a(new A());
    A* origin_a = a.get();
    if (a) {
        printf("a仍然拥有指针");
    }
    std::unique_ptr<A> a2(a.release()); // 转移拥有权
    a2.reset(new A());  // 释放并销毁原有对象,持有一个新对象
    a2.reset(); // 释放并销毁原有对象,等同于 a2 == nullptr
    assert(a2 == nullptr);
    return 0;
}

对于shared_ptr

// 对于shared_ptr有下面几种本身方法
// get 获取智能指针保存的原生指针
// bool 判断该智能指针是否拥有指针
// reset 释放并销毁原生指针。如果参数为一个新指针,将管理这个新指针
// unique 如果引用计数为1返回true,否则返回false
// use_count 返回引用计数大小

对于weak_ptr

weak_ptr可以通过一个shared_ptr创建

// 智能指针有一个通用的规则,就是`->`表示用于调用指针原有的方法,而`.`则表示调用智能指针本身的方法.
// expired 判断所指向的原生指针是否被释放,如果释放了返回true,否则返回false
// use_count 返回原生指针的引用计数
// lock 返回shared_ptr;如果原生指针没有被释放,则返回一个非空的shared_ptr,否则返回一个空的shared_ptr
// reset 将本身置空
int main() {
    std::shared_ptr<A> a(new A());
    std::weak_ptr<A> weak_a = a;    // 不增加引用计数

}

使用建议

1、使用工厂函数而非new构造对象

在上面的代码中需要注意,我们使用std::make_shared代替new的方式创建shared_ptr

因为使用new的方式创建shared_ptr会导致出现两次内存申请,而std::make_shared在内部实现时只会申请一个内存。

2、在类内部调用其他类的方法

不可以在A内部定义B、C的shared_ptr,而是应该使用weak_ptr

class A {
private:
    std::weak_ptr<B> b_;
    std::weak_ptr<C> c_;
public:
    void do_something();
    void set_b_c(const std::shared_ptr<B>& b, const std::shared_ptr<C>& c) {
        b_ = b;
        c_ = c;
    }
};

3、在某类内部将当前对象指针共享给其他对象

#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class A;

class D {
private:
    std::shared_ptr<A> a_;
public:
    D(std::shared_ptr<A>& a): a_(a) {}
};


class A : public std::enable_shared_from_this<A>{
public:
    void new_D()
    {
        // 错误方式,用this指针重新构造shared_ptr,将导致二次释放当前对象,重新创建的shared_ptr与当前对象的shared_ptr没有关系,没有增加当前对象的引用计数
        // 关于这个问题,可以详细地看一下这篇博客:https://www.cnblogs.com/jo3yzhu/p/11358400.html
//        std::shared_ptr<A> this_shared_ptr1(this);
//        std::unique_ptr<D> d1(new D(this_shared_ptr1));
        // 正确方式 对象继承了enable_shared_from_this后,可以通过shared_from_this()获取当前对象的shared_ptr指针。
        std::shared_ptr<A> this_shared_ptr2 = shared_from_this();
        std::unique_ptr<D> d2(new D(this_shared_ptr2));
    }
};

int main() {
    std::shared_ptr<A> a(new A());
    a->new_D();
}

4、 智能指针只能管理堆对象,不能管理栈上对象

栈上对象本身在出栈的时候就会被自动销毁,如果将其指针交给智能指针,会造成对象的二次销毁。

void function() {
    int tmp = 0;
    std::unique_ptr<int> a(tmp);
}

5、不能将this指针直接托管给智能指针

如果对一个类初始化为智能指针,那么在类内部函数用this指针重新构造shared_ptr,不会增加引用计数,会导致当前对象的二次释放。

class A {
public:
    void function() {
        // 错误方式
        std::shared_ptr<A> this_shared_ptr(this);
    }
};
std::shared_ptr<A> e = std::make_shared<E>();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拾牙慧者

欢迎请作者喝奶茶

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

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

打赏作者

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

抵扣说明:

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

余额充值