- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
智能指针是C++语言中一种方便、安全的内存管理工具。智能指针可以自动管理对象的生命周期,避免手动分配和释放内存时可能出现的内存泄漏和悬挂指针等问题。在C++11标准中,引入了三种智能指针:unique_ptr、shared_ptr 和 weak_ptr.
类型 | 含义 | 备注 |
std::unique_ptr | 独占资源所有权的指针。 | |
std::shared_ptr | 共享资源所有权的指针。 | |
std::weak_ptr | 享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期。 |
unique_ptr 是一种独占式智能指针,它拥有对一个对象的唯一所有权,不能与其他智能指针共享对象所有权。当 unique_ptr 超出范围或被显式释放时,它所拥有的对象会被自动销毁.
shared_ptr 是一种共享式智能指针,它可以与其他 shared_ptr 共享一个对象。shared_ptr 使用引用计数技术来记录有多少个 shared_ptr 指向同一个对象,当引用计数为0时,对象会被自动销毁.
weak_ptr 是一种弱引用智能指针,它指向一个由 shared_ptr 管理的对象,但不会增加对象的引用计数。weak_ptr 用于解决循环引用问题,例如两个对象相互引用,导致它们的引用计数永远不会为0,从而无法自动销毁.
使用智能指针可以大大简化内存管理,减少内存泄漏和悬挂指针等问题。同时,智能指针还可以帮助程序员更好地编写多线程程序,避免竞态条件等问题.
下面是一个简单的示例程序,演示了如何使用 unique_ptr 和 shared_ptr:
。
1 #include <iostream> 2 #include <memory> 3 4 struct Foo { 5 Foo() { std::cout << " Foo::Foo\n " ; } 6 ~Foo() { std::cout << " Foo::~Foo\n " ; } 7 }; 8 9 int main() { 10 std::unique_ptr<Foo> p1( new Foo); // 使用 unique_ptr 管理 Foo 对象的生命周期 11 { 12 std::shared_ptr<Foo> p2 = std::make_shared<Foo>(); // 使用 shared_ptr 管理 Foo 对象的生命周期 13 { 14 std::shared_ptr<Foo> p3 = p2; // p2 和 p3 共享 Foo 对象 15 } // p3 超出范围,引用计数减1 16 } // p2 超出范围,引用计数减1,Foo 对象被销毁 17 // p1 超出范围,Foo 对象被销毁 18 return 0 ; 19 }
在上面的示例程序中,我们创建了一个 Foo 对象,并使用 unique_ptr 和 shared_ptr 来管理它的生命周期。在 p2 和 p3 共享 Foo 对象时,它们的引用计数都为2。当 p3 超出范围时,引用计数减1;当 p2 超出范围时,引用计数再减1,Foo 对象被自动销毁。最后,当 p1 超出范围时,Foo 对象再次被销毁.
除了unique_ptr和shared_ptr,C++还有weak_ptr,它是一种不控制对象生命周期的智能指针。它指向一个由shared_ptr管理的对象,但不会增加对象的引用计数。它主要用于解决循环引用问题,例如两个对象相互引用,导致它们的引用计数永远不会为0,从而无法自动销毁.
下面是一个使用weak_ptr的示例程序:
1 #include <iostream> 2 #include <memory> 3 4 struct Foo { 5 void bar() { std::cout << " Foo::bar\n " ; } 6 ~Foo() { std::cout << " Foo::~Foo\n " ; } 7 }; 8 9 int main() { 10 std::shared_ptr<Foo> p1( new Foo); // 使用 shared_ptr 管理 Foo 对象的生命周期 11 std::weak_ptr<Foo> wp1 = p1; // wp1 指向 p1 管理的 Foo 对象,但不增加引用计数 12 { 13 std::shared_ptr<Foo> p2 = wp1. lock (); // 使用 lock() 获取 shared_ptr 14 if (p2) { 15 p2->bar(); // 如果 p2 不为空,调用 bar() 函数 16 } 17 } // p2 超出范围,引用计数减1 18 // wp1 超出范围,因为引用计数已经为0,所以 Foo 对象被销毁 19 return 0 ; 20 }
在这个示例程序中,我们创建了一个 Foo 对象,使用 shared_ptr 和 weak_ptr 来管理它的生命周期。weak_ptr 用于解决循环引用问题,因此它不控制对象生命周期。当最后一个拥有该对象的 shared_ptr 不存在时,该对象被自动销毁。因此,在上面的示例程序中,当 p2 超出范围时,引用计数减1,Foo 对象将被销毁。当 wp1 超出范围时,因为引用计数已经为0,所以 Foo 对象再次被销毁.
另外,C++还提供了一种名为“std::enable_shared_from_this”的模板类,它允许智能指针在对象的成员函数中获取对对象的共享所有权.
下面是一个使用std::enable_shared_from_this的示例程序:
1 #include <iostream> 2 #include <memory> 3 4 struct Foo : std::enable_shared_from_this<Foo> { 5 void bar() { 6 std::cout << " Foo::bar\n " ; 7 auto sptr = shared_from_this(); 8 if (sptr) { 9 sptr-> baz(); 10 } 11 } 12 void baz() { 13 std::cout << " Foo::baz\n " ; 14 } 15 }; 16 17 int main() { 18 std::shared_ptr<Foo> p1( new Foo); // 使用 shared_ptr 管理 Foo 对象的生命周期 19 p1->bar(); // 在 bar() 中使用 enable_shared_from_this 获取对 Foo 对象的共享所有权,并调用 baz() 函数 20 // p1 超出范围,引用计数减1,因为 enable_shared_from_this 不增加引用计数 21 // Foo 对象被销毁 22 return 0 ; 23 }
在这个示例程序中,我们创建了一个 Foo 对象,使用 shared_ptr 管理它的生命周期,并在它的成员函数 bar() 中使用 enable_shared_from_this 获取对它的共享所有权。在 bar() 中,我们还调用了另一个成员函数 baz()。当 p1 超出范围时,引用计数减1,因为 enable_shared_from_this 不增加引用计数,所以 Foo 对象被销毁。当最后一个拥有该对象的 shared_ptr 不存在时,该对象被自动销毁.
另外,C++的智能指针还提供了一些功能,如“std::atomic_shared_ptr”和“std::shared_ptr_future”,可以让你在多线程环境中更安全地使用智能指针。这些功能可以帮助你避免多线程竞争条件等问题.
除此之外,C++还提供了一些更高级的模板库,如“Boost”和“Qt”,其中包含更多高级的智能指针和内存管理功能。例如,Boost库中的“boost::interprocess”库提供了跨进程内存管理和共享访问等功能。这些高级功能可以让你更加灵活地管理内存和开发大规模的应用程序.
总之,C++的智能指针是一个非常强大和灵活的内存管理工具。通过使用不同类型的智能指针和遵循RAII原则,你可以在C++程序中更安全、更有效地管理内存和其他资源.
最后此篇关于C++智能指针的文章就讲到这里了,如果你想了解更多关于C++智能指针的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
是否可以有DropShadowEffect渲染阴影时忽略某些颜色?有某种蒙版(颜色选择性)阴影? 我的问题是什么阴影可以分配给整个视觉元素(图形)。它看起来像这样: 而且我要 注意没有阴影的网格线(除
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, over
有时,当我尝试使用 maven mvn clean install jetty:run 运行我的项目时,它会返回一个错误消息:“地址已在使用中”。 我正在使用 Intellij IDEA 14。 你能
我见过几个数据库缓存引擎,它们都非常愚蠢(即:将此查询缓存 X 分钟)并要求您在 之后手动删除整个缓存存储库>INSERT/UPDATE/DELETE 查询已执行。 大约 2 或 3 年前,我为我正在
我正在寻找例程或寻找错误容忍字符串比较的方法。 比方说,我们有测试字符串 Čakánka - 是的,它包含 CE 字符。 现在,我想接受以下任何字符串作为 OK: 恰坎卡 cákanká ÇaKaNK
大家好 我在 windows xp 系统上使用智能 gwt 2.3 专业版和 Mozilla。 我在上面做了测试应用程序,它运行成功。 现在我想为此应用程序使用开发人员控制台。 我的gwt.xml 编
说,我有 member this.Test (x: 'a) = printfn "generic" 1 member this.Test (x:
我正在努力寻找有关如何将应用程序部署到索尼智能 watch 的任何文档或教程(我正在尝试部署由索尼编写的开源“Eight Puzzle”应用程序,我已将其导入到 Eclipse 中。我有一个三星 S3
我正在寻找一个类似于标准格式化程序的智能 Java 字符串格式化程序: StringBuffer buffer = new StringBuffer(); Formatter form
我有一个智能 JScrollPane,但与其他所有解决方案不同,我想知道如果滚动 Pane 不在底部并且文本是否可以跟随(向上滚动)查看的组件(JTextArea)缓冲区已满。包含功能齐全的代码片段。
我有一个包含 18 个类(class)的项目。它们正在工作线程保存(已检查),没有递归调用,也没有任何复杂的计算。 但是我的IDEA总是说几个小时后 There is not enough memor
我想使用 Smart XLS 库在 C# 中处理 excel 文件(特别是因为它可以生成图表,而且它的价格明显低于 Aspose Cells),但我找不到任何好的例子。我只想知道如何创建和修改图表,有
我正在寻找一个完整的 java 日期管理库,它可以让我理解像这样的字符串: 明天中午 => 2011-10-20 12:00 今天下午 4 点 => 2011-10-20 16:00 等... 但如果
我想打开手机中的文件,通过 watch 中的 Action ... 问题是: Intent intent2 = new Intent(); intent2.setAction(android.cont
我想编译 Sony 为他的 SmartWatch 提供的示例。我按照此 page 中的说明进行操作.但是当我添加 SmartExtensionUtils 项目时,我看到了很多错误,例如:com.son
我有一个 SQL 表:名称、位置、体积 名称为字符串类型 位置是两个 float 类型的字段(纬度和经度) int 类型的体积 我想运行一个 SQL 查询,该查询将对特定范围内的所有位置进行分组并对所
我需要找到当我点击某物时调用的方法。项目很大,自己找会花不少时间。有什么办法可以做到吗?我正在使用 Android Studio,是的,这是我有史以来第一次使用其他人的项目。 最佳答案 我是怎么做到的
我在我的 iMac 上安装了智能 cvs,我已经从 cvs 更新了应用程序。然后我对我的代码和核心数据做了一些更改(核心数据更改是:从核心数据实体中删除一些属性),然后我尝试将更改提交给 cvs,但我
在我的 Java 项目中,我有一个类 Person,它存在于两个具有相同包名 (com.example.beans) 的不同 jar 中。 问题是这个类在jar1中是这样定义的: class Pers
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以
我是一名优秀的程序员,十分优秀!