C++智能指针

//
//  main.cpp
//  C++Test28
//

#include <iostream>
#include <memory>
#include <string>

using namespace std;
// 智能指针
class base {
public:
    base(int _a) : a(_a) { cout << "构造函数" << endl; }
    ~base() { cout << "析构函数" << endl; }
    int a;
};

class B;
class A {
public:
      shared_ptr<B> m_b;
};
class B {
public:
      shared_ptr<A> m_a;
};

int main(int argc, const char *argv[]) {
    unique_ptr<base> up1(new base(2));
    //     unique_ptr<base> up2 = up1;   //编译器提示未定义
    unique_ptr<base> up2 = move(up1); //转移对象的所有权
    //     cout<<up1->a<<endl; //运行时错误
    cout << up2->a << endl; //通过解引用运算符获取封装的原始指针
    up2.reset();            // 显式释放内存
    
    shared_ptr<base> sp1(new base(3));
    shared_ptr<base> sp2 = sp1; //增加引用计数
    cout << "共享智能指针的数量:" << sp2.use_count() << endl; // 2
    sp1.reset();                                               //
    cout << "共享智能指针的数量:" << sp2.use_count() << endl; // 1
    cout << sp2->a << endl;
    auto sp3 = make_shared<base>(4); //利用make_shared函数动态分配内存
    
    
    {
            shared_ptr<A> a(new A); // new出来的A的引用计数此时为1
            shared_ptr<B> b(new B); // new出来的B的引用计数此时为1
            a->m_b = b;             // B的引用计数增加为2
            b->m_a = a;             // A的引用计数增加为2
          
    }
       //b先出作用域,B的引用计数减少为1,不为0;
       //所以堆上的B空间没有被释放,且B持有的A也没有机会被析构,A的引用计数也完全没减少
    
       //a后出作用域,同理A的引用计数减少为1,不为0,所以堆上A的空间也没有被释放
    return 0;
}

//构造函数
//2
//析构函数
//构造函数
//共享智能指针的数量:2
//共享智能指针的数量:1
//3
//构造函数
//析构函数
//析构函数


// 智能指针的陷阱(循环引用的问题)
//循环引用”简单来说就是:两个对象互相使用一个shared_ptr成员变量指向对方会造成循环引用。
//
//即A内部有指向B,B内部有指向A,这样对于A,B必定是在A析构后B才析构,对于B,A必定是在B析构后才析构A,这就是循环引用问题,违反常规,导致内存泄露。
//
//解决循环引用方法:
//
//1. 当只剩下最后一个引用的时候需要手动打破循环引用释放对象。
//2. 当A的生存期超过B的生存期的时候,B改为使用一个普通指针指向A。
//3. 使用weak_ptr打破这种循环引用,因为weak_ptr不会修改计数器的大小,所以就不会产生两个对象互相使用一个shared_ptr成员变量指向对方的问题,从而不会引起引用循环。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

VCHH

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值