weak_ptr解除循环引用

先看一下shared_ptr的正确用法:

class A {
public:
    A() {
        cout << "A::A()" << endl;
    }
    
    ~A() {
        cout << "A::~A()" << endl;
    }
    
    shared_ptr<B> b;
};

class B {
public:
    B() {
        cout << "B::B()" << endl;
    }
    
    ~B() {
        cout << "B::~B()" << endl;
    }
    
public:
    shared_ptr<A> a;
};


/*
 * 
 */
int main(int argc, char** argv) {
    
    shared_ptr<A> x(new A);

此时运行程序,显示:

A::A()
A::~A()


好,A对象被正确的创建和销毁了。

但是注意A对象里面有一个shared_ptr指向B.

现在修改一下代码,让它出现循环引用。

int main(int argc, char** argv) {
    
    shared_ptr<A> x(new A);
    x->b = shared_ptr<B>(new B);
    x->b->a = x;
    return 0;
}
再运行程序,观察结果:

A::A()
B::B()

A和B对象都未释放。为什么?

因为第一行x指向的A对象,A对象的引用计数为1,

第二行 x->b指向B对象,B对象的引用计数为1

第三行B对象里面的a也指向了A对象,因此A对象的引用计数为2

当退出main函数的时候,

1.x的析构函数会将A对象的引用计数从2减到1,但是因为不是0,所以A对象的析构函数不会被调用。

2.因此A里面成员变量b的析构函数就不会被调用。

3.所以B的引用计数也是1. 

4.所以出现了两个内存泄漏,A和B对象都没有被销毁。

为了打破这个循环引用,试试weak_ptr。只需要修改一行代码即可,将B的成员a改成wear_ptr<A>类型。下面是完整代码:

class B;

class A {
public:
    A() {
        cout << "A::A()" << endl;
    }
    
    ~A() {
        cout << "A::~A()" << endl;
    }
    
    shared_ptr<B> b;
};

class B {
public:
    B() {
        cout << "B::B()" << endl;
    }
    
    ~B() {
        cout << "B::~B()" << endl;
    }
    
public:
    weak_ptr<A> a;
};


/*
 * 
 */
int main(int argc, char** argv) {
    
    shared_ptr<A> x(new A);
    x->b = shared_ptr<B>(new B);
    x->b->a = x;
    return 0;
}
运行结果:

A::A()
B::B()
A::~A()
B::~B()

问题解决。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值