MST

星途 面试题库

面试题:C++中std::weak_ptr锁定操作在复杂数据结构中的应用

假设有一个复杂的数据结构,其中包含多个类对象通过std::shared_ptr相互引用,为了避免循环引用问题引入了std::weak_ptr。请描述如何在这个数据结构中正确使用std::weak_ptr的锁定操作,以确保对象在需要时能被安全访问,并提供相关代码示例。
14.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 正确使用std::weak_ptr锁定操作的描述
    • std::weak_ptr是一种弱引用,它指向由std::shared_ptr管理的对象,但不会增加对象的引用计数。
    • 当需要访问std::weak_ptr所指向的对象时,使用lock()成员函数。lock()函数尝试锁定std::weak_ptr,如果对象仍然存在(即对应的std::shared_ptr的引用计数大于0),则返回一个有效的std::shared_ptr,可以通过这个std::shared_ptr安全地访问对象。如果对象已经被销毁(引用计数为0),lock()函数返回一个空的std::shared_ptr
  2. 代码示例
#include <iostream>
#include <memory>

class B;

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

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

int main() {
    std::shared_ptr<A> ptrA = std::make_shared<A>();
    std::shared_ptr<B> ptrB = std::make_shared<B>();

    ptrA->weakB = ptrB;
    ptrB->sharedA = ptrA;

    // 尝试通过weak_ptr锁定对象
    std::shared_ptr<B> lockedB = ptrA->weakB.lock();
    if (lockedB) {
        std::cout << "Successfully locked B" << std::endl;
    } else {
        std::cout << "Failed to lock B" << std::endl;
    }

    // 手动释放ptrA和ptrB
    ptrA.reset();
    ptrB.reset();

    // 再次尝试锁定
    lockedB = ptrA->weakB.lock();
    if (lockedB) {
        std::cout << "Successfully locked B" << std::endl;
    } else {
        std::cout << "Failed to lock B" << std::endl;
    }

    return 0;
}

在上述代码中,首先创建了AB对象,并通过std::shared_ptrstd::weak_ptr建立了相互引用关系。第一次锁定std::weak_ptr时,由于对象存在,lock()函数返回有效的std::shared_ptr。然后手动释放ptrAptrB,再次锁定时,由于对象已被销毁,lock()函数返回空的std::shared_ptr