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

上一篇下一篇

猜你喜欢

热点阅读