c++ 标准中的弱引用
2018-09-10 本文已影响0人
Little熊猫
一 弱指针使用
先看一个例子,没有弱智指针的情况下的嵌套引用
#include <iostream>
#include <memory> // for std::shared_ptr
#include <string>
class Person
{
std::string m_name;
std::shared_ptr<Person> m_partner; // initially created empty
public:
Person(const std::string &name): m_name(name)
{
std::cout << m_name << " created\n";
}
~Person()
{
std::cout << m_name << " destroyed\n";
}
friend bool partnerUp(std::shared_ptr<Person> &p1, std::shared_ptr<Person> &p2)
{
if (!p1 || !p2)
return false;
p1->m_partner = p2;
p2->m_partner = p1;
std::cout << p1->m_name << " is now partnered with " << p2->m_name << "\n";
return true;
}
};
int main()
{
auto lucy = std::make_shared<Person>("Lucy"); // create a Person named "Lucy"
auto ricky = std::make_shared<Person>("Ricky"); // create a Person named "Ricky"
partnerUp(lucy, ricky); // Make "Lucy" point to "Ricky" and vice-versa
return 0;
}
结果是,在嵌套引用的情况下,无法通过智能指针进行回收资源
Lucy created
Ricky created
Lucy is now partnered with Ricky
弱指针是专门针对这种循环应用设计的,使用弱指针后:
#include <iostream>
#include <memory> // for std::shared_ptr and std::weak_ptr
#include <string>
class Person
{
std::string m_name;
std::weak_ptr<Person> m_partner; // note: This is now a std::weak_ptr
public:
Person(const std::string &name): m_name(name)
{
std::cout << m_name << " created\n";
}
~Person()
{
std::cout << m_name << " destroyed\n";
}
friend bool partnerUp(std::shared_ptr<Person> &p1, std::shared_ptr<Person> &p2)
{
if (!p1 || !p2)
return false;
p1->m_partner = p2;
p2->m_partner = p1;
std::cout << p1->m_name << " is now partnered with " << p2->m_name << "\n";
return true;
}
};
int main()
{
auto lucy = std::make_shared<Person>("Lucy");
auto ricky = std::make_shared<Person>("Ricky");
partnerUp(lucy, ricky);
return 0;
}
输出
Lucy created
Ricky created
Lucy is now partnered with Ricky
Ricky destroyed
Lucy destroyed
二 弱指针转换
通过std::weak_ptr的lock接口可以将其转换成std::shared_ptr
#include <iostream>
#include <memory> // for std::shared_ptr and std::weak_ptr
#include <string>
class Person
{
std::string m_name;
std::weak_ptr<Person> m_partner; // note: This is now a std::weak_ptr
public:
Person(const std::string &name) : m_name(name)
{
std::cout << m_name << " created\n";
}
~Person()
{
std::cout << m_name << " destroyed\n";
}
friend bool partnerUp(std::shared_ptr<Person> &p1, std::shared_ptr<Person> &p2)
{
if (!p1 || !p2)
return false;
p1->m_partner = p2;
p2->m_partner = p1;
std::cout << p1->m_name << " is now partnered with " << p2->m_name << "\n";
return true;
}
const std::shared_ptr<Person> getPartner() const { return m_partner.lock(); } // use lock() to convert weak_ptr to shared_ptr
const std::string& getName() const { return m_name; }
};
int main()
{
auto lucy = std::make_shared<Person>("Lucy");
auto ricky = std::make_shared<Person>("Ricky");
partnerUp(lucy, ricky);
auto partner = ricky->getPartner(); // get shared_ptr to Ricky's partner
std::cout << ricky->getName() << "'s partner is: " << partner->getName() << '\n';
return 0;
}
输出:
Lucy created
Ricky created
Lucy is now partnered with Ricky
Ricky's partner is: Lucy
Ricky destroyed
Lucy destroyed
三 weak pointer使用
1) 嵌套引用场景
2) weakpointer 转换为shared_pointer