MST

星途 面试题库

面试题:C++中std::weak_ptr锁定操作的基础应用

请用代码示例说明std::weak_ptr如何通过lock()函数进行锁定操作,以及锁定成功和失败时的返回值情况,并解释其应用场景。
44.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

以下是使用C++ 代码示例说明std::weak_ptr通过lock()函数进行锁定操作,以及锁定成功和失败时的返回值情况:

#include <iostream>
#include <memory>

int main() {
    // 创建一个std::shared_ptr
    std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
    // 创建一个std::weak_ptr指向sharedPtr
    std::weak_ptr<int> weakPtr(sharedPtr);

    // 尝试锁定weakPtr
    std::shared_ptr<int> lockedPtr = weakPtr.lock();

    if (lockedPtr) {
        std::cout << "锁定成功,值为: " << *lockedPtr << std::endl;
    } else {
        std::cout << "锁定失败" << std::endl;
    }

    // 释放sharedPtr
    sharedPtr.reset();

    // 再次尝试锁定weakPtr
    lockedPtr = weakPtr.lock();

    if (lockedPtr) {
        std::cout << "锁定成功,值为: " << *lockedPtr << std::endl;
    } else {
        std::cout << "锁定失败" << std::endl;
    }

    return 0;
}

在上述代码中:

  1. 首先创建了一个std::shared_ptr指向一个int类型的对象,并将其值初始化为42
  2. 接着创建一个std::weak_ptr指向sharedPtr
  3. 第一次调用weakPtr.lock(),此时sharedPtr仍然存在,所以锁定成功,lock()函数返回一个有效的std::shared_ptr,可以通过它访问对象的值。
  4. 然后通过sharedPtr.reset()释放sharedPtr,此时int对象的引用计数变为0,对象被销毁。
  5. 第二次调用weakPtr.lock(),由于指向的对象已经被销毁,所以锁定失败,lock()函数返回一个空的std::shared_ptr

应用场景

  1. 解决循环引用问题:在使用std::shared_ptr时,如果存在循环引用,会导致内存泄漏。例如,类A和类B相互持有对方的std::shared_ptr,这样两个对象的引用计数永远不会为0。使用std::weak_ptr可以打破这种循环引用。比如,类A持有类B的std::weak_ptr,当类B的std::shared_ptr被释放后,类A的std::weak_ptr可以通过lock()函数尝试获取std::shared_ptr,如果获取失败说明类B对象已经不存在。
  2. 缓存场景:在缓存系统中,缓存的对象可能会被其他地方释放(比如缓存淘汰策略)。缓存中可以使用std::weak_ptr指向对象,当需要使用缓存对象时,通过lock()函数尝试锁定,如果锁定成功则说明对象还在,可以继续使用;如果锁定失败则需要重新获取或生成对象。