C++11&14智能指针详解:std::shared_ptr与std::weak_ptr
74 浏览量
更新于2024-08-30
1
收藏 76KB PDF 举报
"C++11和C++14引入了智能指针,作为解决C++动态内存管理问题的一种机制,类似于Java的垃圾回收机制。智能指针通过对象来管理资源指针,并使用计数器跟踪引用数量,当最后一个管理对象销毁时,自动释放内存。本文主要讨论两种常见的智能指针:std::shared_ptr和std::weak_ptr。"
在C++中,动态内存管理是一个关键但又容易出错的部分。传统的裸指针(如`new`分配的内存)需要程序员手动管理内存释放,如果忘记或者管理不当,可能会导致内存泄漏或悬挂指针。为了解决这个问题,C++11引入了智能指针,其中最重要的两种是`std::shared_ptr`和`std::weak_ptr`。
1. `std::shared_ptr`
`std::shared_ptr`是C++标准库中的一个智能指针,它跟踪指向的对象的引用计数。每当创建一个新的`std::shared_ptr`实例来共享同一对象时,引用计数会增加;当`std::shared_ptr`实例被销毁或赋值给其他指针时,引用计数会减少。当引用计数变为零时,`std::shared_ptr`会自动调用`delete`来释放内存。这确保了即使在复杂的所有权结构中,内存也能被正确地管理。
以下是一个`std::shared_ptr`的使用示例:
```cpp
#include <memory>
#include <iostream>
class Test {
public:
Test() { std::cout << "Test()" << std::endl; }
~Test() { std::cout << "~Test()" << std::endl; }
};
int main() {
std::shared_ptr<Test> p1 = std::make_shared<Test>();
std::cout << "1ref: " << p1.use_count() << std::endl;
{
std::shared_ptr<Test> p2 = p1;
std::cout << "2ref: " << p1.use_count() << std::endl;
}
std::cout << "3ref: " << p1.use_count() << std::endl;
return 0;
}
```
在这个例子中,`std::make_shared`用于创建一个`Test`对象并返回一个`std::shared_ptr`。`use_count()`方法用于查询引用计数。当创建`p2`时,`p1`的引用计数增加到2,然后在`p2`离开作用域时减少回1。当`p1`离开作用域时,`~Test()`被调用,表明对象已被删除。
2. `std::weak_ptr`
`std::weak_ptr`是一种弱引用智能指针,它不增加对象的引用计数。它的设计目的是避免循环引用问题,即两个`std::shared_ptr`互相引用,导致它们的引用计数永远不会降为零,从而无法释放内存。`std::weak_ptr`可以观察`std::shared_ptr`所管理的对象,但不会拥有它。只有当`std::shared_ptr`仍然存在时,`std::weak_ptr`才能访问对象。如果所有`std::shared_ptr`实例都已销毁,`std::weak_ptr`尝试访问对象会失败。
使用`std::weak_ptr`的一个常见场景是实现观察者模式,其中观察者不应阻止被观察者被销毁。
```cpp
std::weak_ptr<Test> wp1;
std::shared_ptr<Test> sp1 = std::make_shared<Test>();
wp1 = sp1;
if (std::shared_ptr<Test> sp2 = wp1.lock()) {
// 使用sp2访问对象
} else {
// 对象已被销毁,无法访问
}
```
在这个例子中,`wp1`是一个弱引用,不能直接访问`Test`对象。使用`lock()`方法可以检查对象是否还存在,并在存在时返回一个临时的`std::shared_ptr`。
通过使用智能指针,C++程序员可以更安全地管理动态内存,降低内存泄漏和悬挂指针的风险。`std::shared_ptr`和`std::weak_ptr`提供了强大且灵活的工具,帮助构建健壮的、无内存问题的C++程序。
2018-09-29 上传
2014-06-01 上传
2008-11-06 上传
101 浏览量
2021-10-08 上传
2019-12-18 上传
2014-05-19 上传
点击了解资源详情
weixin_38648037
- 粉丝: 0
- 资源: 929
最新资源
- 新代数控API接口实现CNC数据采集技术解析
- Java版Window任务管理器的设计与实现
- 响应式网页模板及前端源码合集:HTML、CSS、JS与H5
- 可爱贪吃蛇动画特效的Canvas实现教程
- 微信小程序婚礼邀请函教程
- SOCR UCLA WebGis修改:整合世界银行数据
- BUPT计网课程设计:实现具有中继转发功能的DNS服务器
- C# Winform记事本工具开发教程与功能介绍
- 移动端自适应H5网页模板与前端源码包
- Logadm日志管理工具:创建与删除日志条目的详细指南
- 双日记微信小程序开源项目-百度地图集成
- ThreeJS天空盒素材集锦 35+ 优质效果
- 百度地图Java源码深度解析:GoogleDapper中文翻译与应用
- Linux系统调查工具:BashScripts脚本集合
- Kubernetes v1.20 完整二进制安装指南与脚本
- 百度地图开发java源码-KSYMediaPlayerKit_Android库更新与使用说明