智能指针是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 <iostream> #include <memory> 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<MyClass> ptr1 = std::make_unique<MyClass>(10); std::cout << "Value: " << ptr1->getValue() << std::endl; // 尝试复制 unique_ptr 会导致编译错误 // std::unique_ptr<MyClass> ptr2 = ptr1; // 错误:unique_ptr 不可复制 // 可以使用 std::move 转移所有权 std::unique_ptr<MyClass> ptr2 = std::move(ptr1); std::cout << "Value: " << ptr2->getValue() << std::endl; // 现在 ptr1 不再拥有对象,访问它会导致未定义行为 // std::cout << "Value: " << ptr1->getValue() << std::endl; // 避免这样做 // ptr2 在 main 函数结束时会被销毁,MyClass 对象也会被销毁 return 0; }
shared_ptr 则允许多个指针指向同一个对象,它使用引用计数来跟踪有多少个 shared_ptr 指向该对象。只有当引用计数降为零时,对象才会被删除。这使得在多个对象之间共享所有权变得非常方便。但是,循环引用会导致内存泄漏,需要小心。
#include <iostream> #include <memory> 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<MyClass> ptr1 = std::make_shared<MyClass>(20); std::cout << "Value: " << ptr1->getValue() << std::endl; std::cout << "Reference count: " << ptr1.use_count() << std::endl; // 复制 shared_ptr,引用计数增加 std::shared_ptr<MyClass> ptr2 = ptr1; std::cout << "Value: " << ptr2->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 <iostream> #include <memory> 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<MyClass> sharedPtr = std::make_shared<MyClass>(30); std::cout << "Shared pointer value: " << sharedPtr->getValue() << std::endl; std::cout << "Shared pointer reference count: " << sharedPtr.use_count() << std::endl; // 创建一个 weak_ptr,指向同一个 MyClass 对象 std::weak_ptr<MyClass> weakPtr = sharedPtr; std::cout << "Weak pointer expired: " << weakPtr.expired() << std::endl; // 可以使用 weak_ptr 的 lock() 方法获取一个 shared_ptr std::shared_ptr<MyClass> lockedPtr = weakPtr.lock(); if (lockedPtr) { std::cout << "Locked pointer value: " << lockedPtr->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: " << lockedPtr->getValue() << std::endl; } else { std::cout << "Weak pointer is expired." << std::endl; } return 0; }
当你希望对象的所有权是唯一的,并且在 unique_ptr 销毁时自动删除对象时,使用 unique_ptr。例如,在工厂函数中返回新创建的对象,或者在类中拥有一个独占的资源。
循环引用是指两个或多个对象互相持有 shared_ptr,导致引用计数永远不为零,对象永远无法被删除。解决循环引用的方法是使用 weak_ptr。一个对象持有另一个对象的 weak_ptr,而不是 shared_ptr,这样就不会增加引用计数。当需要访问对象时,可以使用 weak_ptr::lock() 方法获取一个 shared_ptr,如果对象已经被删除,lock() 方法会返回 nullptr。
除了解决循环引用问题,weak_ptr 还可以用于缓存。例如,一个缓存对象可以使用 weak_ptr 来持有缓存项,当缓存项不再被其他对象使用时,缓存对象会自动释放缓存项。还可以用于观察者模式,观察者可以使用 weak_ptr 来持有被观察者的引用,当被观察者被删除时,观察者可以自动取消订阅。
以上就是现代C++中的智能指针有哪些区别 unique_ptr shared_ptr weak_ptr对比的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号