【c++】【智能指针】什么情况下不得当智能指针

打印 上一主题 下一主题

主题 981|帖子 981|积分 2943

【c++】【智能指针】什么情况下不得当智能指针
1. 性能开销

大多数场景下用到的都是 unique_ptr


  • 代表的是专属所有权,即由 unique_ptr 管理的内存,只能被一个对象持有。
  • unique_ptr 不支持复制和赋值
  • unique_ptr 在默认情况下和裸指针的大小是一样的。以是内存上没有任何的额外消耗,性能是最优的
shared_ptr:共享所有权


  • 使用 shared_ptr 之前应该考虑,是否真的必要使用 shared_ptr, 而非 unique_ptr。
  • shared_ptr 代表的是共享所有权,即多个 shared_ptr 可以共享同一块内存。
  • shared_ptr 是支持复制的。
  • shared_ptr性能开销更大,内存占用是裸指针的两倍。由于除了要管理一个裸指针外,还要维护一个引用计数。
    因此相比于 unique_ptr, shared_ptr 的内存占用更高
std::shared_ptr 的引用计数机制会引入额外的性能开销,
std::unique_ptr 性能更接近裸指针,但在某些场景下仍存在额外的构造、析构或转移开销。

2. 不得当所有场景



  • 智能指针主要管理堆内存,对栈上对象、全局对象或静态对象无效。
  • 对于某些短生命周期的局部变量,栈分配更高效,无需使用智能指针。
  1. void func() {
  2.     int a = 10;  // 栈上对象,生命周期由作用域自动管理,使用智能指针反而增加不必要的开销。
  3. }
复制代码

3. 循环引用题目



  • std::shared_ptr 存在循环引用的风险,会导致内存走漏。
  • 办理循环引用必要使用 std::weak_ptr,但引入 weak_ptr 也会增长代码复杂度。
   示例:循环引用导致的内存走漏
  1. #include <iostream>
  2. #include <memory>
  3. using namespace std;
  4. struct B;  // 前向声明
  5. struct A {
  6.     shared_ptr<B> ptr;  // A指向B
  7.     ~A() { cout << "A 被销毁" << endl; }
  8. };
  9. struct B {
  10.     shared_ptr<A> ptr;  // B指向A
  11.     ~B() { cout << "B 被销毁" << endl; }
  12. };
  13. int main() {
  14.     auto a = make_shared<A>();
  15.     auto b = make_shared<B>();
  16.     a->ptr = b;
  17.     b->ptr = a;
  18.     // 程序退出时 A 和 B 的析构函数都未调用,发生内存泄漏
  19.     return 0;
  20. }
复制代码

4. 控制权与机动性



  • 在某些情况下,使用裸指针更直观,尤其当对象的生命周期由其他机制管理时
  • 智能指针默认会在生命周期竣事时释放资源,若不小心在非预期时间释放,可能引发步调错误。
   示例:部分 C API 要求使用裸指针,如 malloc()、free()、pthread 等。
  
5. 兼容性



  • 一些 C++ 库和框架可能不兼容智能指针,必要使用裸指针来适配。

6. 代码的可读性和复杂度



  • 滥用智能指针可能会降低代码的可读性,尤其在复杂的条理结构中,明确 shared_ptr、unique_ptr、weak_ptr 之间的关系可能变得困难。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表