美文网首页
智能指针小白理解

智能指针小白理解

作者: FantDing | 来源:发表于2020-07-16 15:42 被阅读0次

unique_ptr

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

使用

  • 简单使用
unique_ptr<int> p1(new int(3));
  • 排他性
unique_ptr<int> p1(new int(3));
unique_ptr<int> 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<int> p1(new int(1));
    unique_ptr<int> p3=move(p1); //p1不再拥有控制权
    if(p1){
        cout<<"p1"<<endl;//不会运行
    }
    else{
        cout<<"p3"<<endl; //会运行
    }
    return 0;
}
  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 = "<<endl;
    }
    A(const A&& other){
        //接受右值的,叫做:移动构造函数
        cout<<"move constructor"<<endl;
    }
};
int main() {
    A a;
    A b;
    b=move(a); //输出move =
    A c=move(a); //输出move constructor
    A d(move(a)); //输出move constructor
    return 0;
}

auto_ptr

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

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

  • 简单

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

share_ptr

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

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

weak_ptr

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

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

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

int main() {
    shared_ptr<A> p1{new A()};
    shared_ptr<B> 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

相关文章

  • 智能指针小白理解

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

  • 智能指针

    理解智能指针从三个层面: 1. 智能指针使用RAII(资源获取初始化)对普通的指针进行封装,使得智能指针实质上是一...

  • C++11中智能指针的原理、使用、实现

    1.智能指针的作用 理解智能指针需要从下面三个层次: 从较浅的层面看,智能指针是利用了一种叫做RAII(资源获取即...

  • 目录

    智能指针(1) 智能指针(2) 智能指针(3) 智能指针之使用 容器 - vector(1) 容器 - vecto...

  • 智能指针到Android引用计数

    智能指针 LightRefBase RefBaseStrongPointerWeakPointer 智能指针 这是...

  • C++面试重点再梳理

    智能指针 请讲一下智能指针原理,并实现一个简单的智能指针 智能指针其实不是一个指针。它是一个用来帮助我们管理指针的...

  • C++研发工程师笔试题/面试题(1-10)

    1. (1) 简述智能指针的原理;(2)c++中常用的智能指针有哪些?(3)实现一个简单的智能指针。 简述智能指针...

  • 第三章 WebKit智能指针详解

    说到智能指针,网上相关资料数不胜数,这里我就我自己的理解给大家分享一下。 1.什么是智能指针 我们在编写c++程序...

  • 第十六章 string类和标准模板库(2)智能指针模板类

    (二)智能指针模板类 智能指针是行为类似指针的类对象,但这种对象还有其他便于管理内存的功能。 1.使用智能指针 (...

  • Rust for cpp devs - 智能指针

    与 cpp 类似,Rust 也有智能指针。Rust 中的智能指针与引用最大的不同是,智能指针 own 内存,而引用...

网友评论

      本文标题:智能指针小白理解

      本文链接:https://www.haomeiwen.com/subject/alpphktx.html