参考网址:https://www.cnblogs.com/feng-sc/p/5710724.html#title13
1、std::shared_ptr
std::make_shared封装了new方法,第一次调用make_shared<>创建类实例时,会对指针的引用计数加1,当检测到引用计数为0,调用析构函数来delete之前std::make_shared创建的指针
代码示例:
#include <iostream>
#include <memory>
using namespace std;
class TestA
{
public:
TestA() {
cout << "testA()" << endl;
}
~TestA() {
cout << "~testA()" << endl;
}
};
int main() {
std::shared_ptr<TestA> p1 = std::make_shared<TestA>();
cout << "1 ref:" << p1.use_count() << endl;
{
std::shared_ptr<TestA> p2 = p1;
cout << "2 ref:" << p1.use_count() << endl;
}
cout << "3 ref:" << p1.use_count() << endl;
//getchar();
//system("pause");
return 0;
}
运行结果:
testA()
1 ref:1
2 ref:2
3 ref:1
~testA()
2、std::weak_ptr
1)std::weak_ptr与std::shared_ptr最大的差别是在赋值时,不会增加智能指针的计数
2)解决shared_ptr相互引用问题
代码示例:
#include <iostream>
#include <memory>
using namespace std;
class TestB;
class TestA
{
public:
TestA() {
cout << "testA()" << endl;
}
~TestA() {
cout << "~testA()" << endl;
}
void ReferTestB(shared_ptr<TestB> ptr) {
mpTestB = ptr;
}
private:
shared_ptr<TestB> mpTestB;
};
class TestB {
public:
TestB() {
cout << "TestB()" << endl;
}
~TestB() {
cout << "~TestB()" << endl;
}
void ReferTestB(shared_ptr<TestA> ptr) {
mpTestA = ptr;
}
private:
shared_ptr<TestA> mpTestA;
};
int main() {
std::shared_ptr<TestA> pLocalA = std::make_shared<TestA>();
std::shared_ptr<TestB> pLocalB = std::make_shared<TestB>();
cout << "1 ref:" << pLocalA.use_count() << endl;
cout << "2 ref:" << pLocalB.use_count() << endl;
pLocalA->ReferTestB(pLocalB);//pLocalB的引用计数加1变成2
pLocalB->ReferTestB(pLocalA);//pLocalA的引用计数加1变成2
cout << "3 ref:" << pLocalA.use_count() << endl;
cout << "4 ref:" << pLocalB.use_count() << endl;
//system("pause");
return 0;
}
运行结果:
testA()
TestB()
1 ref:1
2 ref:1
3 ref:2
4 ref:2
创建的2个对象指针在main调用完成后,没有调用对应的析构函数,为什么?
pLocalA->ReferTestB(pLocalB)执行后,pLocalB被TestA中的mpTestB引用,pLocalB的引用计数加1变成2,在main函数退出时,pLocalB的引用计数减为1,没有达到调用对应析构函数条件;同理对象指针pLocalA不能走到析构函数中。
引进weak_ptr来解决上面问题,示例代码:
class TestA
{
public:
TestA() {
cout << "testA()" << endl;
}
~TestA() {
cout << "~testA()" << endl;
}
void ReferTestB(shared_ptr<TestB> ptr) {
mpTestB = ptr;
}
private:
weak_ptr<TestB> mpTestB;
};
class TestB {
public:
TestB() {
cout << "TestB()" << endl;
}
~TestB() {
cout << "~TestB()" << endl;
}
void ReferTestB(shared_ptr<TestA> ptr) {
mpTestA = ptr;
}
private:
weak_ptr<TestA> mpTestA;
};
int main() {
std::shared_ptr<TestA> pLocalA = std::make_shared<TestA>();
std::shared_ptr<TestB> pLocalB = std::make_shared<TestB>();
cout << "1 ref:" << pLocalA.use_count() << endl;
cout << "2 ref:" << pLocalB.use_count() << endl;
pLocalA->ReferTestB(pLocalB);
pLocalB->ReferTestB(pLocalA);
cout << "3 ref:" << pLocalA.use_count() << endl;
cout << "4 ref:" << pLocalB.use_count() << endl;
//system("pause");
return 0;
}
运行结果:
testA()
TestB()
1 ref:1
2 ref:1
3 ref:1
4 ref:1
~TestB()
~testA()
lock()的作用:
把std::weak_ptr类型转换成std::shared_ptr类型,然后对TestA对象进行调用
class TestB;
class TestA
{
public:
TestA() {
cout << "testA()" << endl;
}
~TestA() {
cout << "~testA()" << endl;
}
void ReferTestB(shared_ptr<TestB> ptr) {
mpTestB = ptr;
}
void TestWork(){
std::cout << "TestA::TestWork()" << std::endl;
}
private:
weak_ptr<TestB> mpTestB;
};
class TestB {
public:
TestB() {
cout << "TestB()" << endl;
}
~TestB() {
//把std::weak_ptr类型转换成std::shared_ptr类型,然后对TestA对象进行调用
std::shared_ptr<TestA> tmp = mpTestA.lock();
tmp->TestWork();
std::cout << "ref of mpTestA:" << tmp.use_count() << std::endl;
cout << "~TestB()" << endl;
}
void ReferTestB(shared_ptr<TestA> ptr) {
mpTestA = ptr;
}
void TestWork() {
std::cout << "TestB::TestWork()" << std::endl;
}
private:
weak_ptr<TestA> mpTestA;
};
int main() {
std::shared_ptr<TestA> pLocalA = std::make_shared<TestA>();
std::shared_ptr<TestB> pLocalB = std::make_shared<TestB>();
cout << "1 ref:" << pLocalA.use_count() << endl;
cout << "2 ref:" << pLocalB.use_count() << endl;
pLocalA->ReferTestB(pLocalB);
pLocalB->ReferTestB(pLocalA);
cout << "3 ref:" << pLocalA.use_count() << endl;
cout << "4 ref:" << pLocalB.use_count() << endl;
//system("pause");
return 0;
}
运行结果:
testA()
TestB()
1 ref:1
2 ref:1
3 ref:1
4 ref:1
TestA::TestWork()
ref of mpTestA:2
~TestB()
~testA()
网友评论