发布于: 2023-8-10最后更新: 2023-10-9字数 00 分钟

智能指针

C++11中智能指针的分类。是线程安全的嘛,如果不是使用时怎么处理。
在C++11中,提供了四种类型的智能指针:
  1. std::unique_ptr: 独特所有权,不能被复制,但可以通过std::move进行所有权转移。
  1. std::shared_ptr: 共享所有权,可以有多个shared_ptr指向同一个对象,shared_ptr使用引用计数来跟踪有多少个智能指针指向同一个资源,当最后一个shared_ptr被销毁时,资源也将被释放。
  1. std::weak_ptr: 弱引用,它可以指向一个由shared_ptr管理的对象,但它不参与引用计数,主要用来解决shared_ptr可能会引发的循环引用问题。
  1. std::auto_ptr: 这是一个被废弃的智能指针,它试图实现独占所有权,但其语义在C++标准中并不怎么清晰,因此在C++11中被std::unique_ptr所取代。

线程安全

关于线程安全性,除std::shared_ptr外,其他智能指针都不是线程安全的。注意,std::shared_ptr的线程安全性仅限于你可以在不同的线程中安全地使用单个shared_ptr的副本。然而,让多个线程同时访问同一shared_ptr实例(例如,一个线程读取,另一个线程写入)可能会导致数据竞争和未定义的行为。因此,如果在多线程环境中使用智能指针,你需要自己进行适当的同步。
以下是一个示例,展示如何在多线程环境中使用std::mutex来同步对std::shared_ptr的访问:
在这个示例中,我们使用了std::mutexstd::lock_guard来保证在多个线程中对p的访问是互斥的,这样就可以避免数据竞争和未定义的行为。
std::shared_ptr的线程安全性仅限于可以在不同的线程中安全地使用单个shared_ptr的副本,正确使用的示例
以下是一个示例,展示std::shared_ptr线程安全性的正确使用:
在这个示例中,我们在主线程中创建了一个shared_ptrp),然后在创建新线程时,我们将p传递给thread_func。每次thread_func被调用时,都会创建一个新的shared_ptr副本(即函数参数p),这个副本与原始的shared_ptr(主线程中的p)指向同一个对象。由于std::shared_ptr的线程安全性,这种用法是安全的,每个线程都有自己的shared_ptr副本,且不会发生数据竞争。

share ptr自己实现

实现示例

unique ptr简单实现

以下是 std::unique_ptr 的简化实现,以便你可以理解其工作原理:
在上述代码中,当我们尝试复制一个 unique_ptr 时,编译器会报错,因为复制构造函数和复制赋值运算符已被删除。当我们尝试移动一个 unique_ptr 时(例如,将其传递给另一个函数,或从另一个函数返回它),移动构造函数或移动赋值运算符会被调用,它们会从源 unique_ptr 中删除指针,并在目标 unique_ptr 中设置该指针。这就确保了每个 unique_ptr 都有其独占的对象,从而实现了独占所有权。

C++上层应用(常见)
C++上层应用(常见)