目录
shared_ptr带来的问题:
在交叉引用时,会造成堆上资源无法释放的问题。
使用weak_ptr弱引用就可以打破这个交叉引用,因为weak_ptr不改变引用记数。
但当用weak_ptr指针访问成员方法时,需加 lock 函数,提升为强引用。
标准库weak_ptr弱引用验证:
头文件:#include <memory>
自定义一个类用:
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
A()
{
cout << "A的构造" << endl;
}
~A()
{
cout << "A的析构" << endl;
}
void slots_function()
{
cout << "加油,挣大钱" << endl;
}
};
主函数:
int main()
{
// 验证弱引用
//在栈上创建
shared_ptr<A> ptr1 (new A);
shared_ptr<A> ptr2 = ptr1;
cout << ptr2.use_count() << endl; //>>2
weak_ptr<A> ptr3 = ptr1;
cout << ptr2.use_count() << endl; //>>2
cout << ptr3.use_count() << endl; //>>2 ,证明weak_ptr不改变计数
cout << "----------------------1" << endl;
// ptr3.slots_function(); //报错
ptr3.lock()->slots_function(); //弱引用只能通过lock方法调用对象方法
cout << "----------------------2" << endl;
cout << ptr3.use_count() << endl; //2
cout << ptr3.expired() << endl; //0 ,作用是判断use_count == 0,返回bool
cout << "-----------------------3" << endl;
//析构所有指针
ptr1.~shared_ptr();
ptr2.~shared_ptr();
ptr3.~weak_ptr();
cout << "---------------------4" << endl;
cout << ptr3.use_count() << endl; //0
cout << ptr3.expired() << endl; //1
ptr3.lock()->slots_function(); //当count为零,虽然shared_ptr指向的堆区空间不能用,
ptr2->slots_function(); //但栈上对象依然存在,shared_ptr的方法还能调用.
return 0;
}
运行结果:
标准库中weak_ptr交叉引用的验证:
定义两个可相互引用的类:
#include <iostream>
#include <memory>
using namespace std;
class B;
class A
{
public:
weak_ptr<B> ptr_b;
public:
A()
{
cout << "A的构造" << endl;
}
~A()
{
cout << "A的析构" << endl;
}
void slots_function()
{
cout << "加油,挣大钱" << endl;
}
};
class B
{
public:
weak_ptr<A> ptr_a;
public:
B()
{
cout << "B的构造" << endl;
}
~B()
{
cout << "B的析构" << endl;
}
//用于升级成强引用,调用别人的方法.
shared_ptr<A> lock()
{
return (shared_ptr<A>) ptr_a;
}
//可以在类中调用交叉对象的方法
void signals()
{
shared_ptr<A> temp = ptr_a.lock();
if(temp != nullptr)
{
temp->slots_function();
}
}
};
主函数:
// 验证交叉引用
shared_ptr<A> ptr4(new A);
shared_ptr<B> ptr5(new B);
cout << ptr4.use_count() << endl; //1
cout << ptr5.use_count() << endl; //1
ptr4->slots_function(); //有输出
ptr5->signals(); //无输出,原因是还没有引用A类对象
cout << "--------------1" << endl;
//交叉引用
ptr4->ptr_b = ptr5;
ptr5->ptr_a = ptr4;
cout << ptr4.use_count() << endl; //1,因为类里交叉引用用的wek_ptr
cout << ptr5.use_count() << endl; //1,所以,并未让计数器增加
cout << "---------------2" << endl;
//调用自身方法可以
ptr4->slots_function();
ptr5->signals();
cout << "--------------3" << endl;
// ptr5->slots_function(); //错误,交叉引用后也不能直接调别人的方法,需加lock
ptr5->lock()->slots_function();
cout << ptr5.use_count() << endl; //1
return 0;
运行结果: