智能指针是c++++中自动管理内存的工具,主要包括unique_ptr、shared_ptr和weak_ptr。1. unique_ptr用于独占所有权,不可复制,转移需用std::move,销毁时自动删除对象;2. shared_ptr允许多个指针共享同一对象,通过引用计数管理生命周期,但需注意循环引用问题;3. weak_ptr作为弱引用不增加引用计数,用于解决循环引用及实现缓存等场景。合理选择智能指针可避免内存泄漏并提升效率。

智能指针,说白了,就是帮你自动管理内存的指针。现代 C++ 里,它们已经是标配了,unique_ptr、shared_ptr 和 weak_ptr,各有各的用处和侧重点,用错了地方,轻则效率打折,重则内存泄漏。

unique_ptr、shared_ptr、weak_ptr 就像是内存管理战场上的三员大将,各有千秋,用对了地方才能发挥最大威力。

解决方案
首先,unique_ptr,顾名思义,它所指向的对象只能被一个 unique_ptr 拥有。这意味着,所有权是独占的,不能简单地复制。当 unique_ptr 销毁时,它所指向的对象也会被自动删除。这避免了忘记 delete 造成的内存泄漏。
立即学习“C++免费学习笔记(深入)”;
#include #include class MyClass {public: MyClass(int value) : value_(value) { std::cout << "MyClass constructed with value: " << value_ << std::endl; } ~MyClass() { std::cout << "MyClass destructed with value: " << value_ << std::endl; } int getValue() const { return value_; }private: int value_;};int main() { // 创建一个 unique_ptr,指向一个 MyClass 对象 std::unique_ptr ptr1 = std::make_unique(10); std::cout << "Value: " <getValue() << std::endl; // 尝试复制 unique_ptr 会导致编译错误 // std::unique_ptr ptr2 = ptr1; // 错误:unique_ptr 不可复制 // 可以使用 std::move 转移所有权 std::unique_ptr ptr2 = std::move(ptr1); std::cout << "Value: " <getValue() << std::endl; // 现在 ptr1 不再拥有对象,访问它会导致未定义行为 // std::cout << "Value: " <getValue() << std::endl; // 避免这样做 // ptr2 在 main 函数结束时会被销毁,MyClass 对象也会被销毁 return 0;}
shared_ptr 则允许多个指针指向同一个对象,它使用引用计数来跟踪有多少个 shared_ptr 指向该对象。只有当引用计数降为零时,对象才会被删除。这使得在多个对象之间共享所有权变得非常方便。但是,循环引用会导致内存泄漏,需要小心。

#include #include class MyClass {public: MyClass(int value) : value_(value) { std::cout << "MyClass constructed with value: " << value_ << std::endl; } ~MyClass() { std::cout << "MyClass destructed with value: " << value_ << std::endl; } int getValue() const { return value_; }private: int value_;};int main() { // 创建一个 shared_ptr,指向一个 MyClass 对象 std::shared_ptr ptr1 = std::make_shared(20); std::cout << "Value: " <getValue() << std::endl; std::cout << "Reference count: " << ptr1.use_count() << std::endl; // 复制 shared_ptr,引用计数增加 std::shared_ptr ptr2 = ptr1; std::cout << "Value: " <getValue() << std::endl; std::cout << "Reference count: " << ptr1.use_count() << std::endl; std::cout << "Reference count: " << ptr2.use_count() << std::endl; // ptr1 和 ptr2 都指向同一个对象,该对象在 main 函数结束时会被销毁一次 return 0;}
最后,weak_ptr 是一种“弱引用”,它指向由 shared_ptr 管理的对象,但不增加引用计数。weak_ptr 可以用来观察对象是否仍然存在,而不会阻止对象被删除。这对于解决循环引用问题非常有用。
#include #include class MyClass {public: MyClass(int value) : value_(value) { std::cout << "MyClass constructed with value: " << value_ << std::endl; } ~MyClass() { std::cout << "MyClass destructed with value: " << value_ << std::endl; } int getValue() const { return value_; }private: int value_;};int main() { // 创建一个 shared_ptr,指向一个 MyClass 对象 std::shared_ptr sharedPtr = std::make_shared(30); std::cout << "Shared pointer value: " <getValue() << std::endl; std::cout << "Shared pointer reference count: " << sharedPtr.use_count() << std::endl; // 创建一个 weak_ptr,指向同一个 MyClass 对象 std::weak_ptr weakPtr = sharedPtr; std::cout << "Weak pointer expired: " << weakPtr.expired() << std::endl; // 可以使用 weak_ptr 的 lock() 方法获取一个 shared_ptr std::shared_ptr lockedPtr = weakPtr.lock(); if (lockedPtr) { std::cout << "Locked pointer value: " <getValue() << std::endl; std::cout << "Shared pointer reference count: " << sharedPtr.use_count() << std::endl; } else { std::cout << "Weak pointer is expired." << std::endl; } // 释放 shared_ptr sharedPtr.reset(); std::cout << "Shared pointer reference count: " << sharedPtr.use_count() << std::endl; std::cout << "Weak pointer expired: " << weakPtr.expired() << std::endl; // 再次尝试使用 weak_ptr 的 lock() 方法 lockedPtr = weakPtr.lock(); if (lockedPtr) { std::cout << "Locked pointer value: " <getValue() << std::endl; } else { std::cout << "Weak pointer is expired." << std::endl; } return 0;}
何时使用 unique_ptr?
当你希望对象的所有权是唯一的,并且在 unique_ptr 销毁时自动删除对象时,使用 unique_ptr。例如,在工厂函数中返回新创建的对象,或者在类中拥有一个独占的资源。
shared_ptr 如何避免循环引用导致的内存泄漏?
循环引用是指两个或多个对象互相持有 shared_ptr,导致引用计数永远不为零,对象永远无法被删除。解决循环引用的方法是使用 weak_ptr。一个对象持有另一个对象的 weak_ptr,而不是 shared_ptr,这样就不会增加引用计数。当需要访问对象时,可以使用 weak_ptr::lock() 方法获取一个 shared_ptr,如果对象已经被删除,lock() 方法会返回 nullptr。
weak_ptr 的使用场景有哪些?
除了解决循环引用问题,weak_ptr 还可以用于缓存。例如,一个缓存对象可以使用 weak_ptr 来持有缓存项,当缓存项不再被其他对象使用时,缓存对象会自动释放缓存项。还可以用于观察者模式,观察者可以使用 weak_ptr 来持有被观察者的引用,当被观察者被删除时,观察者可以自动取消订阅。
以上就是现代C++中的智能指针有哪些区别 unique_ptr shared_ptr weak_ptr对比的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1465844.html
微信扫一扫
支付宝扫一扫