智能指针
C++11中智能指针的分类。是线程安全的嘛,如果不是使用时怎么处理。
在C++11中,提供了四种类型的智能指针:
std::unique_ptr
: 独特所有权,不能被复制,但可以通过std::move
进行所有权转移。
std::shared_ptr
: 共享所有权,可以有多个shared_ptr
指向同一个对象,shared_ptr
使用引用计数来跟踪有多少个智能指针指向同一个资源,当最后一个shared_ptr
被销毁时,资源也将被释放。
std::weak_ptr
: 弱引用,它可以指向一个由shared_ptr
管理的对象,但它不参与引用计数,主要用来解决shared_ptr
可能会引发的循环引用问题。
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::mutex
和std::lock_guard
来保证在多个线程中对p
的访问是互斥的,这样就可以避免数据竞争和未定义的行为。std::shared_ptr
的线程安全性仅限于可以在不同的线程中安全地使用单个shared_ptr
的副本,正确使用的示例以下是一个示例,展示
std::shared_ptr
线程安全性的正确使用:在这个示例中,我们在主线程中创建了一个
shared_ptr
(p
),然后在创建新线程时,我们将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
都有其独占的对象,从而实现了独占所有权。- 作者:Olimi
- 链接:https://olimi.icu/article/cdc7f710-3a5c-4753-99b1-35bed8781c1e
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。