智能指针使用摘要

最近复习了一下智能指针相关内容,做个摘要。

1. 如果没有拷贝、赋值等要求,优先选用scoped_ptr

2. 如果不需要放入容器中(放入容器中的元素类型必须是能拷贝的),优先选用scoped_ptr

3. 如果不需要自定义删除器,优先选用scoped_ptr

4. 尽量不要用scoped_array管理new出来的数组,改用vector代替

5. 只能显式调用构造函数来初始化。

shared_ptr<int> sp(new int(8)); //正确
shared_ptr<int> sp = new int(8); //错误

6. 如果要管理除了内存之外的其它资源,则需要自定义删除器,此时要用shared_ptr。

shared_ptr<FILE> fp(fopen("kof.txt", "r"), fclose);

7. 对于scoped_ptr和shared_ptr,如果使用默认构造函数,则其持有的是空指针,而不是野指针

8. 注意区别scoped_ptr和shared_ptr的reset方法,两者都是停止对原指针的使用,改为持有空指针。不同之处是前者会引发原指针的删除操作和相应的析构,后者是将原指针的引用计数减1,若减1后引用计数为0,才会引发原指针的删除操作和相应的析构

9. scoped_ptr不支持比较运算,shared_ptr支持比较运算,包括相等、不等和小于

10. 用static_pointer_cast<T>()等来进行shared_ptr的指针类型转换,不能使用原始的强制类型转换,也不能使用static_cast<T>()

11. 尽量使用make_shared代替new来生成shared_ptr对象

12. 要有将shared_ptr用于工厂模式和桥接模式的意识

13. 利用shared_ptr的删除器功能,实现退出作用域时调用任意函数

#include <iostream>
#include <boost/smart_ptr.hpp>

class KOF {
};

// 在func中做任意事情,不一定只能释放资源
// 美中不足的是这里的参数arg无法传进来,就像线程函数那样
// 由于void*指针可以指向任意类型,那么也可以指向KOF类型,所以满足func的参数要求
void func(void *arg) {
    arg = arg;
    std::cout << "func is called" << std::endl;
}

int main() {
    boost::shared_ptr<KOF> sp(nullptr, func);

    std::cout << "Hello, world" << std::endl;

    return 0;
}

14. 尽量不要用shared_array管理new出来的数组,改用vector代替

15. 客户不要去管理被智能指针包装起来的原始指针,让智能指针自己管理,如有必要,定制删除器即可

16. 避免循环引用造成的资源泄露

#include <iostream>
#include <boost/smart_ptr.hpp>

class B;

class A {
public:
    A() { std::cout << "A constructor is called" << std::endl; }

    ~A() { std::cout << "A destructor is called" << std::endl; }

    void set(boost::shared_ptr<B> sp) { sp_ = sp; }
private:
    boost::shared_ptr<B> sp_;
};

class B {
public:
    B() { std::cout << "B constructor is called" << std::endl; }

    ~B() { std::cout << "B destructor is called" << std::endl; }

    void set(boost::shared_ptr<A> sp) { sp_ = sp; }
private:
    //boost::shared_ptr<A> sp_; // 用这一句代替下一句,会造成循环引用,A和B的析构函数均不会被调用
    boost::weak_ptr<A> sp_;     // 用这一句代替上一句,可以解决循环引用,A和B都被析构
};

int main() {
    boost::shared_ptr<A> pa(boost::make_shared<A>());
    boost::shared_ptr<B> pb(boost::make_shared<B>());
    pa->set(pb);
    pb->set(pa);

    return 0;
}

17. 某些情况下,当需要使用某个类T的this指针作为参数时,要将该类T继承自boost::enable_shared_from_this<T>类,并在需要this指针的地方用shared_from_this()函数代替,这里的shared_from_this()函数时继承来的,不需要作用域符限定


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值