您的位置:首页 > 娱乐 > 明星 > 网站建设要求_网络营销系统推广方案_兰州网络推广推广机构_sem是什么品牌

网站建设要求_网络营销系统推广方案_兰州网络推广推广机构_sem是什么品牌

2025/6/30 13:56:10 来源:https://blog.csdn.net/weixin_50993868/article/details/147307308  浏览:    关键词:网站建设要求_网络营销系统推广方案_兰州网络推广推广机构_sem是什么品牌
网站建设要求_网络营销系统推广方案_兰州网络推广推广机构_sem是什么品牌

很棒的问题!C++ 智能指针是现代 C++ 的精髓之一。

C++ 智能指针 = 自动管理内存的对象,像指针一样使用,但自动释放资源,不用你手动 delete。


🧠 一句话概括

智能指针类型C++ 版本特点推荐使用?
auto_ptrC++98 / C++03独占所有权,赋值会转移指针❌ 已弃用
shared_ptrC++11+引用计数共享所有权✅ 推荐

✅ 示例对比

🔹 auto_ptr 示例(已弃用❗)

#include <iostream>
#include <memory>  // auto_ptr 也在 memory 中using namespace std;int main() {auto_ptr<int> p1(new int(10));  // p1 拥有该内存auto_ptr<int> p2 = p1;          // p1 的所有权转移给了 p2,p1 变成空指针!cout << *p2 << endl;// cout << *p1 << endl; // ❌ 崩溃!p1 已不再拥有资源return 0;
}
✨ auto_ptr 特点:
  • 所有权会在拷贝构造或赋值时自动转移
  • 原来的指针会被置空
  • 不能多个指针共享同一资源
  • C++11 中已被弃用!

🔹 shared_ptr 示例(现代首选 ✅)

#include <iostream>
#include <memory>  // for shared_ptrusing namespace std;int main() {shared_ptr<int> p1 = make_shared<int>(20);  // 引用计数 +1shared_ptr<int> p2 = p1;                    // 引用计数 +1(现在是 2 个 shared_ptr 管一个对象)cout << "p1: " << *p1 << ", p2: " << *p2 << endl;cout << "use_count: " << p1.use_count() << endl;  // 输出 2p1.reset();  // 引用计数 -1,但对象还没被释放,因为 p2 还在cout << "After p1.reset(), use_count: " << p2.use_count() << endl;return 0;  // 最后 p2 离开作用域,引用计数为 0,内存自动释放
}
✨ shared_ptr 特点:
  • 多个指针共享资源
  • 自动维护引用计数
  • 引用计数为 0 时,自动释放内存
  • 安全、推荐用在多个地方持有对象时

🚫 auto_ptr 的危险场景(bug 多)

void pass(auto_ptr<int> p) {// 拿到资源,但调用后原来的指针被清空,副作用巨大!
}int main() {auto_ptr<int> p1(new int(5));pass(p1);cout << *p1 << endl;  // ❌ 运行时崩溃!p1 已无效
}

✅ shared_ptr 的正确传参方式

void use(shared_ptr<int> p) {cout << "in use(): " << *p << endl;
}int main() {shared_ptr<int> p1 = make_shared<int>(99);use(p1);  // 安全传参,引用计数 +1,函数结束后自动减少cout << "Back in main: " << *p1 << endl;
}

✅ 总结对比表

对比点auto_ptrshared_ptr
所有权独占,赋值会转移引用计数,共享所有权
拷贝行为所有权转移,原指针失效引用计数 +1,不转移所有权
生命周期管理自动释放自动释放(引用为 0)
安全性⚠️ 容易出 bug✅ 安全
C++版本支持C++98/03,已弃用C++11+
推荐使用?❌ 不建议✅ 推荐

如果你还想了解 unique_ptr(只能有一个拥有者)或者 weak_ptr(解决 shared_ptr 循环引用问题)我也可以继续讲!要不要顺便来一发?😄


🎯 常用智能指针类型

智能指针所属头文件所有权引用计数特点说明
unique_ptr<memory>独占无法拷贝,只能转移
shared_ptr<memory>共享引用计数 + 自动释放
weak_ptr<memory>弱引用🚫不增加引用计数,避免循环引用

🧪 用法示例合集(涵盖所有智能指针)


✅ 1. unique_ptr 基本用法(独占资源)

#include <iostream>
#include <memory>int main() {std::unique_ptr<int> up = std::make_unique<int>(42);std::cout << "*up = " << *up << std::endl;// std::unique_ptr<int> up2 = up; ❌ 错误,不能拷贝std::unique_ptr<int> up2 = std::move(up);  // ✅ 所有权转移if (!up) {std::cout << "up 已被转移" << std::endl;}return 0;
}

✅ 2. shared_ptr 基本用法(共享资源)

#include <iostream>
#include <memory>int main() {std::shared_ptr<int> sp1 = std::make_shared<int>(100);std::shared_ptr<int> sp2 = sp1;  // 引用计数 +1std::cout << "use_count = " << sp1.use_count() << std::endl;  // 输出 2sp1.reset();  // 引用计数 -1std::cout << "use_count = " << sp2.use_count() << std::endl;  // 输出 1return 0;
}

✅ 3. weak_ptr 解决 shared_ptr 循环引用问题

#include <iostream>
#include <memory>struct Node {std::shared_ptr<Node> next;std::weak_ptr<Node> prev;  // ✅ 避免循环引用
};int main() {auto node1 = std::make_shared<Node>();auto node2 = std::make_shared<Node>();node1->next = node2;node2->prev = node1;  // weak_ptr 不会增加引用计数std::cout << "node1 use_count = " << node1.use_count() << std::endl;  // 输出 1std::cout << "node2 use_count = " << node2.use_count() << std::endl;  // 输出 2return 0;
}

明白了!你是卡在“为什么 a 和 b 离开作用域,内存还释放不了”这一点。这个是 shared_ptr 的循环引用核心问题,我们来从内存角度 + 图解角度彻底解释清楚👇


🧠 你以为这样:

{std::shared_ptr<Node> a = std::make_shared<Node>();std::shared_ptr<Node> b = std::make_shared<Node>();
}

作用域一结束,a 和 b 自动销毁,内存应该释放对吧?✅ 正常情况下确实会释放。


🚨 但如果它们互相引用对方,事情就变了!

struct Node {std::shared_ptr<Node> next;std::shared_ptr<Node> prev;  // ❌ 大坑就在这里
};
int main() {std::shared_ptr<Node> a = std::make_shared<Node>();std::shared_ptr<Node> b = std::make_shared<Node>();a->next = b;  // b 的引用计数 +1b->prev = a;  // a 的引用计数 +1 ❗❗❗return 0;  // 看似结束了,其实它们还“互相抓着对方”
}

🔄 实际发生了什么?(引用关系图)

变量被谁引用use_count
amain 中的变量 + b->prev(shared)2
bmain 中的变量 + a->next(shared)2

❌ 当你执行 return 0;

a 和 b 在栈上销毁,main 中的 shared_ptr 被释放

但是!还剩下彼此内部 shared_ptr 指着对方!

所以引用计数各为 1,没人能先释放谁,就像两个互相抱住的人,谁也不先放手。
🎯 这就是循环引用!


✅ 4. unique_ptr 管理数组资源

#include <iostream>
#include <memory>int main() {std::unique_ptr<int[]> arr = std::make_unique<int[]>(5);for (int i = 0; i < 5; ++i)arr[i] = i * 10;for (int i = 0; i < 5; ++i)std::cout << arr[i] << " ";std::cout << std::endl;return 0;
}

☑️ 注意:数组要写 int[],不能用普通 unique_ptr<int>


✅ 5. 自定义 deleter 用法(shared_ptr)

#include <iostream>
#include <memory>void custom_deleter(int* p) {std::cout << "custom deleting " << *p << std::endl;delete p;
}int main() {std::shared_ptr<int> sp(new int(777), custom_deleter);  // 指定删除器std::cout << *sp << std::endl;return 0;
}

🧠 最佳实践小贴士

场景推荐用法
创建新对象make_shared<T>() / make_unique<T>()
自定义资源释放(文件句柄等)shared_ptr<T>(ptr, deleter)
避免 shared_ptr 循环引用使用 weak_ptr 弱引用
管理数组资源unique_ptr<T[]>
函数参数只读引用const std::shared_ptr<T>&

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com