智能指针小白理解

unique_ptr

uniqut_ptr排他性拥有权的智能指针,即一个对象资源只能同时被一个unique_ptr指向

使用

  • 简单使用
unique_ptr p1(new int(3));
  • 排他性
unique_ptr p1(new int(3));
unique_ptr p2=p1; // 会出错
  1. 为什么会出错?
    1.1. 为了完成语义上的unique,代码中将拷贝构造函数/赋值运算符给delete了,导致无法调用。类似下面:
/*初始化,使用的是拷贝构造函数,不是赋值运算符*/
class A{
public:
    A(){}
    A& operator=(const A& other)=delete ;
    A(const A& other)=delete ;
};
int main() {
    A a;
    A b;
    b=a; //出错,赋值运算符给delete

   A c(a);// 出错,拷贝构造函数delete
   A  d=a;// 出错,拷贝构造函数delete[初始化,使用的是拷贝构造函数,不是赋值运算符]
}
  • 控制权转移: move
int main() {
    unique_ptr p1(new int(1));
    unique_ptr p3=move(p1); //p1不再拥有控制权
    if(p1){
        cout<<"p1"<
  1. 为什么这边又可以复制了: 因为move把原对象(示例中是a)变成右值,回去调用对应的移动构造函数/移动赋值函数unique_ptr在这两个函数中完成了控制权的转移
class A{
public:
    A(){}
    A& operator=(const A& other)=delete ;
    A(const A& other)=delete ;
    A& operator=(const A&& other){
        //接受右值的,叫做:移动赋值函数
        cout<<"move = "<

auto_ptr

已经废除,相当于使用move的unique_ptr

  • 为何弃用 ref
    auto_ptr采用copy语义来转移指针资源,转移指针资源的所有权的同时将原指针置为NULL,这跟通常理解的copy行为是不一致的(不会修改原数据),而这样的行为在有些场合下不是我们希望看到的。

  • 简单

auto_ptr p1{new int(1)};
auto_ptr p2=p1; // 相当于unique_ptr的:p2=move(p1),但是是通过赋值完成的
  • 内部实现 ref

share_ptr

能够使用多个(智能)指针指向同一块地址,使用引用计数做内存管理

  • 循环引用问题
class B;
class A{
public:
    shared_ptr b;
    A(){cout<<"A"<& b){this->b=b;}
};
class B{
public:
    shared_ptr a;
    B(){cout<<"B"<& a){this->a=a;}
    ~B(){cout<<"~B"< p1{new A()};
    shared_ptr p2{new B()};
    p1->set(p2);
    p2->set(p1);
    cout<
UDmX4O.png
  • 可以看到,new A()申请的空间有2个指针指向它; 同理new B()。因为引用计数不为0,所以不会释放这两块空间

weak_ptr

搭配shared_ptr解决循环引用,weak_ptr只引用,不计数

class B;
class A {
public:
    weak_ptr b; //这里改成weak_ptr
    A() { cout << "A" << endl; }
    ~A() { cout << "~A" << endl; }
    void set(const shared_ptr &b) { this->b = b; }
};

class B {
public:
    weak_ptr a; //这里改成weak_ptr
    B() { cout << "B" << endl; }
    void set(const shared_ptr &a) { this->a = a; }
    ~B() { cout << "~B" << endl; }
};

int main() {
    shared_ptr p1{new A()};
    shared_ptr p2{new B()};
    p1->set(p2);
    p2->set(p1);
    cout << p1.use_count() << endl;  // output: 1
    cout << p2.use_count() << endl; // output: 1
    // 会调用析构函数,输出
    /*
        A
        B
        1
        1
        ~B
        ~A
     * */
    return 0;
}
image.png

你可能感兴趣的:(智能指针小白理解)