智能指针通过RAII机制实现自动内存管理,其中std::unique_ptr适用于独占所有权场景,如std::vector存储动态对象时避免内存泄漏;std::shared_ptr用于共享所有权,配合std::weak_ptr解决循环引用问题;优先使用std::make_unique和std::make_shared确保异常安全与性能优化,结合移动语义和STL算法提升容器操作效率。

C++智能指针在STL容器中的应用,对我来说,是现代C++内存管理方案里最核心也最优雅的一环。它本质上是将资源管理(尤其是内存释放)的责任从手动操作转移到了编译期和运行期,通过RAII(资源获取即初始化)机制,让开发者能更专注于业务逻辑,而非那些恼人的内存泄漏或野指针问题。这不仅仅是语言特性上的进步,更是编程哲学上的一次解放,它让STL容器这种强大的数据结构工具,在管理动态分配对象时变得前所未有的安全和便捷。
在C++中,尤其是在使用STL容器存储动态分配的对象时,传统的裸指针管理方式往往伴随着巨大的心智负担和潜在的错误。试想一下,一个
std::vector<MyObject*>
MyObject*
delete
智能指针的引入,特别是
std::unique_ptr
std::shared_ptr
std::weak_ptr
std::unique_ptr
unique_ptr
unique_ptr
std::vector<std::unique_ptr<MyObject>>
unique_ptr
MyObject
MyObject
立即学习“C++免费学习笔记(深入)”;
而
std::shared_ptr
shared_ptr
shared_ptr
shared_ptr
std::map<Key, std::shared_ptr<CachedData>>
std::weak_ptr
shared_ptr
shared_ptr
shared_ptr
std::unique_ptr
std::shared_ptr
在STL容器中选择
std::unique_ptr
std::shared_ptr
如果你的设计理念是“独占”,即容器中的每个元素都应该拥有它所管理的对象,并且当这个元素被移除或容器本身被销毁时,对应的对象也应该随之销毁,那么
std::unique_ptr
例如,一个游戏场景中,你有一个
std::vector<std::unique_ptr<GameObject>>
GameObject
GameObject
unique_ptr
std::move
std::vector<std::unique_ptr<MyResource>> resources; resources.push_back(std::make_unique<MyResource>(/* args */)); // ... // 转移所有权到另一个vector std::vector<std::unique_ptr<MyResource>> otherResources; otherResources.push_back(std::move(resources[0])); // resources[0]现在是空的
另一方面,如果你的设计需要“共享”,即同一个对象可能被多个容器元素、甚至多个不同的容器或程序模块共同引用和管理,并且只有当所有引用都消失时,对象才应该被销毁,那么
std::shared_ptr
一个常见的场景是资源管理器。你可能有一个
std::map<std::string, std::shared_ptr<Texture>>
shared_ptr
shared_ptr
PHP经典实例(第2版)能够为您节省宝贵的Web开发时间。有了这些针对真实问题的解决方案放在手边,大多数编程难题都会迎刃而解。《PHP经典实例(第2版)》将PHP的特性与经典实例丛书的独特形式组合到一起,足以帮您成功地构建跨浏览器的Web应用程序。在这个修订版中,您可以更加方便地找到各种编程问题的解决方案,《PHP经典实例(第2版)》中内容涵盖了:表单处理;Session管理;数据库交互;使用We
453
std::map<std::string, std::shared_ptr<Texture>> textureCache; // ... 加载纹理并存入缓存 std::shared_ptr<Texture> playerTexture = textureCache["player_skin.png"]; std::shared_ptr<Texture> enemyTexture = textureCache["enemy_skin.png"]; // 假设敌人也用这个纹理 // 此时playerTexture和enemyTexture共享同一个Texture对象
我的经验是,优先考虑
std::unique_ptr
std::shared_ptr
智能指针虽好,但用起来也有些地方需要留心,否则可能适得其反。我见过不少开发者在初次接触智能指针时,会掉进一些小坑。
一个很常见的误区是混用裸指针和智能指针,或者说,从一个裸指针多次创建
std::shared_ptr
MyObject* rawPtr = new MyObject();
std::shared_ptr<MyObject> s1(rawPtr);
std::shared_ptr<MyObject> s2(rawPtr);
MyObject
get()
shared_ptr
std::make_shared
// 错误示例:双重释放 MyObject* obj = new MyObject(); std::shared_ptr<MyObject> p1(obj); std::shared_ptr<MyObject> p2(obj); // 危险!obj会被释放两次 // 正确做法:使用std::make_shared std::shared_ptr<MyObject> p3 = std::make_shared<MyObject>();
另一个需要注意的陷阱是std::shared_ptr
std::shared_ptr
std::shared_ptr
std::weak_ptr
shared_ptr
weak_ptr
weak_ptr::lock()
shared_ptr
lock()
shared_ptr
class B; // 前向声明
class A {
public:
std::shared_ptr<B> b_ptr;
~A() { std::cout << "A destroyed" << std::endl; }
};
class B {
public:
std::shared_ptr<A> a_ptr; // 错误:这里应该用weak_ptr
~B() { std::cout << "B destroyed" << std::endl; }
};
// 循环引用会导致A和B都不会被销毁至于性能考量,
std::unique_ptr
std::unique_ptr
unique_ptr
std::shared_ptr
shared_ptr
std::shared_ptr
std::shared_ptr
我个人在使用
std::shared_ptr
std::make_shared
shared_ptr
随着C++标准的发展,智能指针与STL容器的结合变得更加流畅和强大。现代C++为我们提供了更多优雅的工具和实践方式。
首先,std::make_unique
std::make_shared
shared_ptr
foo(std::shared_ptr<T>(new T()), std::shared_ptr<U>(new U()))
new T()
std::shared_ptr<T>
new U()
new T()
std::make_shared<T>()
std::make_unique<T>()
// 现代C++创建智能指针的推荐方式 std::unique_ptr<MyObject> obj1 = std::make_unique<MyObject>(arg1, arg2); std::shared_ptr<MyObject> obj2 = std::make_shared<MyObject>(arg1, arg2);
其次,C++11引入的移动语义对
std::unique_ptr
std::unique_ptr
std::vector
push_back
emplace_back
unique_ptr
std::vector<std::unique_ptr<Widget>> widgets;
widgets.reserve(10); // 预留空间,避免不必要的重新分配和移动
for (int i = 0; i < 10; ++i) {
widgets.emplace_back(std::make_unique<Widget>(i)); // 直接在vector内部构造unique_ptr
}
// 假设我们想把第5个Widget移动到另一个vector
std::vector<std::unique_ptr<Widget>> otherWidgets;
if (widgets.size() > 5) {
otherWidgets.push_back(std::move(widgets[5])); // 移动所有权
widgets.erase(widgets.begin() + 5); // 移除旧位置的空unique_ptr
}再次,STL算法与智能指针的结合。STL的各种算法,如
std::sort
std::for_each
std::transform
struct Data { int value; std::string name; };
std::vector<std::shared_ptr<Data>> dataVec;
dataVec.push_back(std::make_shared<Data>(Data{10, "Apple"}));
dataVec.push_back(std::make_shared<Data>(Data{5, "Banana"}));
dataVec.push_back(std::make_以上就是C++智能指针应用 STL内存管理方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号