一篇搞懂C++ STL智能指针std::shared_ptr
【摘要】 @TOC 前言在 C++ 编程中,智能指针是一种重要的工具,用于自动管理动态分配的内存。std::shared_ptr 是 C++11 引入的智能指针之一,它允许多个 std::shared_ptr 实例共享对同一个对象的所有权。std::shared_ptr 通过引用计数机制来管理内存的生命周期,确保对象在最后一个 std::shared_ptr 被销毁时才释放。 为什么使用 std::s...
@TOC
前言
在 C++ 编程中,智能指针是一种重要的工具,用于自动管理动态分配的内存。std::shared_ptr 是 C++11 引入的智能指针之一,它允许多个 std::shared_ptr 实例共享对同一个对象的所有权。std::shared_ptr 通过引用计数机制来管理内存的生命周期,确保对象在最后一个 std::shared_ptr 被销毁时才释放。
为什么使用 std::shared_ptr
- 共享所有权:
std::shared_ptr允许多个指针共享对同一个对象的所有权,适用于需要多个实体引用同一对象的场景。 - 自动内存管理:智能指针自动管理对象的生命周期,避免了内存泄漏的问题。
- 引用计数:内置的引用计数机制确保对象在所有
std::shared_ptr实例都不再使用时才被释放。
std::shared_ptr 与 std::unique_ptr 的区别
-
所有权管理:
std::unique_ptr:独占所有权,确保同一时间只有一个智能指针拥有对象的所有权,不能被复制,只能移动。std::shared_ptr:允许多个智能指针共享同一个对象的所有权,通过引用计数机制来管理对象的生命周期。
-
引用计数:
std::unique_ptr:没有引用计数,简单高效。std::shared_ptr:使用引用计数来管理对象的生命周期,较为复杂但支持共享所有权。
std::shared_ptr 的构造函数和操作函数
构造函数
-
默认构造函数
std::shared_ptr();std::shared_ptr<int> p; // 创建一个空的 shared_ptr -
构造函数(原始指针)
explicit std::shared_ptr(T* ptr);std::shared_ptr<int> p(new int(10)); // 使用原始指针构造 shared_ptr -
拷贝构造函数
std::shared_ptr(const std::shared_ptr& other);std::shared_ptr<int> p1(new int(20)); std::shared_ptr<int> p2(p1); // 拷贝构造 -
移动构造函数
std::shared_ptr(std::shared_ptr&& other) noexcept;std::shared_ptr<int> p1(new int(30)); std::shared_ptr<int> p2(std::move(p1)); // 移动构造
成员函数
-
resetvoid reset(T* ptr = nullptr);std::shared_ptr<int> p(new int(40)); p.reset(new int(50)); // 释放旧对象并拥有新对象 -
getT* get() const noexcept;std::shared_ptr<int> p(new int(60)); int* rawPtr = p.get(); // 获取原始指针 -
use_countlong use_count() const noexcept;std::shared_ptr<int> p1(new int(70)); std::shared_ptr<int> p2 = p1; std::cout << "Use count: " << p1.use_count() << std::endl; // 输出引用计数 -
operator*T& operator*() const;std::shared_ptr<int> p(new int(80)); std::cout << *p << std::endl; // 访问管理的对象 -
operator->T* operator->() const;struct MyClass { void display() const { std::cout << "Hello" << std::endl; } }; std::shared_ptr<MyClass> p(new MyClass()); p->display(); // 访问对象的成员函数
如果有多个 std::shared_ptr 指向同一内存
std::shared_ptr 允许多个智能指针实例共享对同一个对象的所有权。引用计数会随着 std::shared_ptr 实例的创建和销毁而增加或减少。当最后一个 std::shared_ptr 实例被销毁时,管理的对象才会被释放。
std::shared_ptr<int> p1(new int(90));
std::shared_ptr<int> p2 = p1; // 共享所有权
std::cout << "Use count: " << p1.use_count() << std::endl; // 输出引用计数
p1.reset(); // 释放 p1 的所有权
std::cout << "Use count after reset p1: " << p2.use_count() << std::endl; // 输出引用计数
p2.reset(); // 释放 p2 的所有权,对象将被销毁
示例代码
下面的示例展示了 std::shared_ptr 的各种构造函数和操作函数的用法:
#include <iostream>
#include <memory>
struct MyClass {
MyClass(int v) : value(v) {}
int value;
void display() const { std::cout << "Value: " << value << std::endl; }
};
int main() {
// 使用默认构造函数
std::shared_ptr<int> p1;
// 使用原始指针构造函数
std::shared_ptr<int> p2(new int(10));
std::cout << "p2: " << *p2 << std::endl;
// 使用拷贝构造函数
std::shared_ptr<int> p3(p2);
std::cout << "p3: " << *p3 << std::endl;
// 使用移动构造函数
std::shared_ptr<int> p4(std::move(p2));
if (!p2) {
std::cout << "p2 is now empty" << std::endl;
}
// 使用 reset 函数
p4.reset(new int(20));
std::cout << "p4: " << *p4 << std::endl;
// 使用 get 函数
std::shared_ptr<MyClass> p5(new MyClass(30));
MyClass* rawPtrClass = p5.get();
rawPtrClass->display();
// 使用 use_count 函数
std::cout << "Use count of p5: " << p5.use_count() << std::endl;
// 使用 operator* 和 operator->
std::shared_ptr<MyClass> p6(new MyClass(40));
std::cout << "p6 value: " << p6->value << std::endl;
(*p6).display();
// 演示多个 shared_ptr
std::shared_ptr<int> p7(new int(50));
std::shared_ptr<int> p8 = p7; // 共享所有权
std::cout << "Use count: " << p7.use_count() << std::endl;
p7.reset(); // 释放 p7 的所有权
std::cout << "Use count after reset p7: " << p8.use_count() << std::endl;
p8.reset(); // 释放 p8 的所有权,对象将被销毁
return 0;
}
总结
std::shared_ptr 是一个强大的智能指针,用于管理动态分配的内存,并允许多个指针共享同一对象的所有权。通过引用计数机制,std::shared_ptr 确保对象在最后一个指针被销毁时才释放,避免了内存泄漏和悬空指针的问题。了解 std::shared_ptr 的构造函数和操作函数,有助于在需要共享对象所有权的场景中更安全、有效地管理内存。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)