标准库头文件:memory

1.常用变量

unique_ptr    //模板类,拥有独有对象所有权语义的智能指针
shared_ptr    //模板类,拥有共享对象所有权语义的智能指针,不会因为weak_ptr也指向同一个对象而引用计数加1
weak_ptr    //模板类,由shared_ptr所管理的对象的弱引用,避免循环引用
auto_ptr    //模板类,C++17中移除

2.初始化

shared_ptr ptr; //ptr相当于nullptr
shared_ptr ptr1(new T()); //从new操作符的返回值构造,并自动管理内存
shared_ptr ptr2(ptr1);  //调用拷贝构造函数,会让引用计数加1
shared_ptr ptr3(new T()); ptr3=ptr2; //原先ptr3指向的内存被释放,指向新的内存,ptr1引用计数加1
unique_ptr ptr1(new T());
//unique_ptr不能进行拷贝和赋值,但是可以移动拷贝和移动赋值
unique_ptr ptr2=std::move(ptr1); 

3.常用操作

std::make_unique(5);//将5变成独有对象,c++14支持
unique_ptr::get();//返回指向被管理对象的指针,如果无被管理对象,则为nullptr
unique_ptr::release();//释放被管理对象的所有权
unique_ptr::swap(unique_ptr& other);//交换两个被管理对象
std::make_shared(5);//将5变成共享对象,注意make_shared(x)和shared_ptr(x)的区别,一个是构造,一个是赋值
shared_ptr::get();//返回指向被管理对象的指针,如果无被管理对象,则为nullptr
shared_ptr::swap(unique_ptr& other);//交换两个被管理对象
shared_ptr::reset(new int);//重置被管理对象的指针
shared_ptr::unique();//判断指针是否unique,即非空,且引用计数为0
shared_ptr::use_count();//返回共享对象的引用计数
weak_ptr::use_count();//返回管理该对象的shared_ptr对象数量,将shared_ptr对象赋给weak_ptr对象,引用计数加一
weak_ptr::expired();//检查被引用的对象是否已删除 
weak_ptr::lock();//创建被引用的对象的shared_ptr 
auto_ptr::get();//返回指向被管理对象的指针,如果无被管理对象,则为nullptr
auto_ptr::release();//释放被管理对象的所有权

4.注意事项

  • 如果要多个线程读写同一个shared_ptr对象,那么需要加锁
  • 一个shared_ptr对象可被多个线程同时读取
  • 两个shared_ptr对象可以被两个线程同时写入
  • 当shared_ptr作为函数参数,且是值传递时,则引用计数会加1,因为有临时变量的生成,如果是引用传递,则引用计数不会加1,作为返回值的原理相同
  • 慎用shared_ptr的引用传递,而不是值传递,因为传递引用时,引用计数并不会加1,但是这时又将对象销毁的话,就会导致引用计数为0,查看以下用例
class Obj{};

class Num{
    void push(shared_ptr& obj){//此处使用引用没有问题,引用计数会少加1,相比传值,只有入队时引用计数加1
        queue_.push(obj);//如果是传值,传入时引用计数加1,push结束,引用计数又减1,真正也只有入队时引用计数加1
    }
    shared_ptr pop(){
        shared_ptr& obj = queue_.front();//此处使用引用有问题,obj指向的对象的引用计数没有加1
        //即还是1,但是执行下一句pop时,会发生一次析构,导致引用计数为0,即obj中指向的对象已销毁,只是函数指针与原先一致
        queue_.pop();
        return obj;
    }
    queue> queue_;
};

//但是有的情况下,使用shared_ptr必须要传引用
class Num{
    void getObj(shared_ptr& obj){
        obj = obj_;//假如这个地方不是用引用,那么obj_实际上是赋值给obj的副本,这个副本的改动,是不影响外面的实参的
    }
    Obj = obj_;
}

Num num;
shared_ptr obj;
num.getObj(obj);

你可能感兴趣的:(C++学习,c++,shared_ptr,unique_ptr)