MST

星途 面试题库

面试题:C++ 中 std::weak_ptr 的基本使用限制

请简述 C++ 中 std::weak_ptr 在基本使用场景下有哪些常见的使用限制,并举例说明如何避免因这些限制导致的问题。
31.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

使用限制

  1. 空指针访问风险std::weak_ptr 本身不持有对象,通过 lock() 获取 std::shared_ptr 时可能返回空指针。
  2. 过期问题:如果指向的对象已被销毁,std::weak_ptr 就会过期,lock() 会返回空指针。
  3. 线程安全问题:在多线程环境下,std::weak_ptr 本身不是线程安全的,当多个线程同时访问和修改 std::weak_ptr 时可能导致数据竞争。

避免方法及示例

  1. 空指针访问风险
    #include <iostream>
    #include <memory>
    
    int main() {
        std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
        std::weak_ptr<int> weakPtr = sharedPtr;
    
        std::shared_ptr<int> lockedPtr = weakPtr.lock();
        if (lockedPtr) {
            std::cout << "Value: " << *lockedPtr << std::endl;
        } else {
            std::cout << "Object has been destroyed." << std::endl;
        }
        return 0;
    }
    
    通过 lock() 后检查返回的 std::shared_ptr 是否为空来避免空指针访问。
  2. 过期问题
    #include <iostream>
    #include <memory>
    #include <vector>
    
    std::weak_ptr<int> globalWeakPtr;
    
    void checkWeakPtr() {
        std::shared_ptr<int> lockedPtr = globalWeakPtr.lock();
        if (lockedPtr) {
            std::cout << "Object is still alive: " << *lockedPtr << std::endl;
        } else {
            std::cout << "Object has been destroyed." << std::endl;
        }
    }
    
    int main() {
        {
            std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
            globalWeakPtr = sharedPtr;
            checkWeakPtr();
        }
        checkWeakPtr();
        return 0;
    }
    
    每次使用 std::weak_ptr 前通过 lock() 检查对象是否过期。
  3. 线程安全问题
    #include <iostream>
    #include <memory>
    #include <thread>
    #include <mutex>
    
    std::weak_ptr<int> globalWeakPtr;
    std::mutex weakPtrMutex;
    
    void threadFunction() {
        std::unique_lock<std::mutex> lock(weakPtrMutex);
        std::shared_ptr<int> lockedPtr = globalWeakPtr.lock();
        if (lockedPtr) {
            std::cout << "Thread sees value: " << *lockedPtr << std::endl;
        } else {
            std::cout << "Thread sees object destroyed." << std::endl;
        }
    }
    
    int main() {
        std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
        globalWeakPtr = sharedPtr;
    
        std::thread t1(threadFunction);
        std::thread t2(threadFunction);
    
        t1.join();
        t2.join();
    
        return 0;
    }
    
    使用互斥锁(如 std::mutex)来保护对 std::weak_ptr 的访问,确保多线程环境下的安全。