如何解决shared_ptr、unique_ptr 和weak_ptr 的最佳用例是什么?
虽然通过了解 std::shared_ptr
、std::unique_ptr
和 std::weak_ptr
很容易了解它们,但我似乎很难理解它们在什么情况下被证明是有用。
谁能举出其中三个的一两个具体例子?
解决方法
我假设你知道每个智能指针的作用,所以我不打算解释它们。相反,我将举例说明我如何在自己的代码中或从我使用过的需要它们的库中使用它们。
std::unique_ptr:可以从 API 返回,表示资源需要由调用者管理,共享对象不安全。例如,gRPC 创建 CompletionQueue
这样的实例。 CompletionQueue
具有敏感的生命周期和同步要求。通过返回 unique_ptr
,很明显调用者负责生命周期管理,并且共享 CompletionQueue
变得很麻烦。共享它仍然不是不可能的(可以从 unique_ptr
获取原始指针或使用对 unique_ptr
的引用,这两者都是典型的代码异味)。
std::shared_ptr/std::weak_ptr:不是最简单的用例,但我们开始......
AudioPlayer::AudioPlayer() {
thread_local std::weak_ptr<AudioPlayerMixer> mixedOutput;
if (mixedOutput.expired()) {
m_mixedOutput = std::make_shared<AudioPlayerMixer>();
mixedOutput = m_mixedOutput;
} else {
m_mixedOutput = mixedOutput.lock();
}
}
在此示例中,线程上的所有 AudioPlayer
实例都需要使用 AudioPlayerMixer
将其音频混合在一起。因此,每个 AudioPlayer
都有一个 shared_ptr<AudioPlayerMixer>
,因此当最后一个持有 AudioPlayer
的 shared_ptr
实例被销毁时,混合器也会被销毁。 thread_local
的使用只是便于每个线程拥有唯一的 AudioPlayerMixer
。 thread_local
的 AudioPlayerMixer
存储不应延长混频器的寿命,因为 AudioPlayerMixer
的寿命取决于 AudioPlayer
实例的存在(即没有 {{ 1}} => 没有 AudioPlayer
) - 这就是使用 AudioPlayerMixer
的原因。 weak_ptr
表示没有在此线程上创建 mixedOutput.expired() == true
或删除所有先前存在的玩家。 AudioPlayer
表示此线程上存在另一个 mixedOutput.expired() == false
,当前 AudioPlayer
需要将 AudioPlayer
获取到同一个混频器。请注意,在多个线程中使用 shared_ptr
和 shared_ptr
时必须小心,因为它们不是线程安全的。在此示例中,weak_ptr
以及 thread_local
仅在同一线程中创建和销毁的事实确保它是安全的。
当然,这一切都可以在没有智能指针的情况下完成,但智能指针有助于更好地传达代码的意图。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。