shared_ptr 循环引用以及解决办法

发布时间 2024-01-13 20:45:33作者: 洛笔达

问题代码

#include <memory>
#include <stdio.h>
using namespace std;

class A;
class B
{
public:
    B() { printf("B()\n"); }
    ~B() { printf("~B()\n"); }
	void print(){ printf("B\n"); }
    shared_ptr<A> ptrA_;
};

class A
{
public:
    A() {printf("A()\n"); }
    ~A() { printf("~A()\n"); }
    shared_ptr<B> ptrB_;
};

int main()
{
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();

    a->ptrB_ = b;
    b->ptrA_ = a;

    printf("user count:%d %d\n", a->ptrB_.use_count(), b->ptrA_.use_count());
    return 0;
}

最后打印:
user count:2 2
循环引用,内存泄漏

改进版本

使用

 shared_ptr<A> ptrA_ 改为 weakptr<A> ptrA_

但是类里面无法使用ptrA_, 因为weakptr只有访问权限没有控制权限
如果需要控制ptrA_, 可以这样写:

in A:
    void A::func() {
        shared_ptr<B> b = ptrB_.lock();
        if (nullptr != b) {
            b->print();
        }
    }
in:B
void print() { printf("a good function B\n"); }

最终代码如下

#include <memory>
#include <stdio.h>
using namespace std;

class A;
class B
{
public:
    B() { printf("B()\n"); }
    ~B() { printf("~B()\n"); }
    void print() { printf("a good function B\n"); }
    weak_ptr<A> ptrA_;
};

class A
{
public:
    A() {printf("A()\n"); }
    ~A() { printf("~A()\n"); }
    void func() {
        shared_ptr<B> b = ptrB_.lock();
        if (nullptr != b) {  //这里很重要,来判断是否能拿到制作的控制权
            b->print();
        }
    }
    weak_ptr<B> ptrB_;
};

int main()
{
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();

    a->ptrB_ = b;
    b->ptrA_ = a;
    a->func();

    printf("user count:%d %d\n", a->ptrB_.use_count(), b->ptrA_.use_count());
    return 0;
}