unique_ptr通过独占所有权和RAII原则自动管理内存,防止泄漏;它不可复制,只能通过std::move转移所有权,确保同一时间仅一个指针管理对象,提升异常安全性和代码清晰度。

unique_ptr
unique_ptr
在C++中,使用
unique_ptr
<memory>
最推荐的创建
unique_ptr
std::make_unique
#include <iostream>
#include <memory> // 包含unique_ptr的定义
#include <string>
class MyObject {
public:
std::string name;
MyObject(std::string n) : name(std::move(n)) {
std::cout << "MyObject " << name << " created." << std::endl;
}
~MyObject() {
std::cout << "MyObject " << name << " destroyed." << std::endl;
}
void doSomething() const {
std::cout << "MyObject " << name << " is doing something." << std::endl;
}
};
int main() {
// 1. 使用std::make_unique 创建unique_ptr
// 这是最佳实践,它能保证内存分配和unique_ptr构造的原子性。
std::unique_ptr<MyObject> ptr1 = std::make_unique<MyObject>("Object A");
ptr1->doSomething(); // 像原始指针一样访问成员
(*ptr1).doSomething(); // 也可以这样访问
// 2. 直接使用new关键字创建 (不推荐,但了解其机制)
// std::unique_ptr<MyObject> ptr2(new MyObject("Object B"));
// ptr2->doSomething();
// 3. 所有权转移:unique_ptr是move-only类型,不能复制,只能通过std::move转移所有权。
// std::unique_ptr<MyObject> ptr_copy = ptr1; // 编译错误!不能复制
std::unique_ptr<MyObject> ptr_moved = std::move(ptr1); // 所有权从ptr1转移到ptr_moved
// 此时ptr1不再拥有对象,其内部指针为空
if (!ptr1) {
std::cout << "ptr1 is now empty after move." << std::endl;
}
ptr_moved->doSomething(); // ptr_moved现在是唯一所有者
// 4. reset() 方法:释放当前对象,并可以选择管理新对象
std::cout << "--- Calling reset() ---" << std::endl;
ptr_moved.reset(new MyObject("Object C")); // 释放"Object A",并管理新创建的"Object C"
ptr_moved->doSomething();
// 5. release() 方法:放弃所有权,返回原始指针,但不删除对象
std::cout << "--- Calling release() ---" << std::endl;
MyObject* rawPtr = ptr_moved.release(); // ptr_moved放弃所有权,rawPtr指向"Object C"
// 此时ptr_moved为空
if (!ptr_moved) {
std::cout << "ptr_moved is empty after release." << std::endl;
}
rawPtr->doSomething();
// ⚠️ 注意:现在rawPtr指向的对象需要手动delete,否则会内存泄漏!
delete rawPtr; // 手动释放"Object C"
// 当main函数结束时,所有剩余的unique_ptr(比如在这里没有其他了)会自动销毁其管理的对象。
// 如果上面没有delete rawPtr,那么"Object C"的析构函数就不会被调用。
std::cout << "--- End of main ---" << std::endl;
return 0;
}这段代码展示了
unique_ptr
reset()
release()
unique_ptr
立即学习“C++免费学习笔记(深入)”;
unique_ptr
当我们谈论C++中的内存管理,原始指针(raw pointers)无疑是基础,但它们也带来了无尽的烦恼和潜在的错误。我个人觉得,
unique_ptr
首先,最显著的优势是自动化内存管理,这基于RAII(Resource Acquisition Is Initialization)原则。使用原始指针时,每当你
new
delete
delete
unique_ptr
unique_ptr
delete
其次,它提供了独占所有权的清晰语义。一个
unique_ptr
unique_ptr
delete
unique_ptr
std::move
unique_ptr
unique_ptr
再者,
unique_ptr
new
delete
delete
unique_ptr
简而言之,
unique_ptr
unique_ptr
unique_ptr
shared_ptr
unique_ptr
unique_ptr
unique_ptr
那么,如果我想把一个
unique_ptr
unique_ptr
unique_ptr
unique_ptr
std::move
当你对一个
unique_ptr
std::move
unique_ptr
unique_ptr
std::move
unique_ptr
让我们看几个例子:
显式转移所有权:
std::unique_ptr<MyObject> originalPtr = std::make_unique<MyObject>("Initial Object");
std::unique_ptr<MyObject> newOwnerPtr = std::move(originalPtr); // 所有权从 originalPtr 转移到 newOwnerPtr
// 此时,originalPtr 内部的指针已经变为空(nullptr),不再管理任何对象。
// newOwnerPtr 现在是 "Initial Object" 的唯一所有者。
if (!originalPtr) {
std::cout << "originalPtr is now empty." << std::endl;
}
newOwnerPtr->doSomething();这里,
originalPtr
std::move
nullptr
newOwnerPtr
newOwnerPtr
函数返回unique_ptr
std::move
unique_ptr
std::unique_ptr<MyObject> createObject(const std::string& name) {
return std::make_unique<MyObject>(name); // 编译器通常会在这里执行移动或RVO
}
// 在main或其他函数中调用
std::unique_ptr<MyObject> myObj = createObject("Returned Object");
myObj->doSomething();这里,
createObject
unique_ptr
myObj
函数参数传递unique_ptr
unique_ptr
std::move
void takeOwnership(std::unique_ptr<MyObject> obj) {
// obj 现在是这个对象的唯一所有者
obj->doSomething();
// 当 obj 超出此函数作用域时,它所管理的对象会被销毁
}
// 调用
std::unique_ptr<MyObject> tempObj = std::make_unique<MyObject>("Temporary Object");
takeOwnership(std::move(tempObj)); // tempObj 的所有权转移给函数参数 obj
// 此时 tempObj 已经为空
if (!tempObj) {
std::cout << "tempObj is empty after passing to function." << std::endl;
}这种方式意味着函数将获得对象的所有权,并在函数结束时负责销毁它。如果只是想让函数临时使用对象而不获取所有权,通常会传递原始指针或引用:
void useObject(MyObject* obj)
void useObject(MyObject& obj)
总的来说,
unique_ptr
std::move
unique_ptr
unique_ptr
shared_ptr
在C++现代编程中,
unique_ptr
shared_ptr
我的经验是,首先考虑使用unique_ptr
unique_ptr
shared_ptr
1. 优先选择unique_ptr
unique_ptr
unique_ptr
unique_ptr
shared_ptr
unique_ptr
适用场景:
std::unique_ptr<Base> createDerived() {
return std::make_unique<Derived>();
}unique_ptr
class Widget {
std::unique_ptr<InternalData> data;
public:
Widget() : data(std::make_unique<InternalData>()) {}
// ...
};std::vector<std::unique_ptr<MyObject>>
2. 何时考虑shared_ptr
shared_ptr
shared_ptr
shared_ptr
适用场景:
shared_ptr
shared_ptr
需要注意的陷阱:
shared_ptr
shared_ptr
std::weak_ptr
shared_ptr
总结一下我的思考流程:
unique_ptr
shared_ptr
weak_ptr
通过遵循这个思考过程,我们可以在项目中做出明智的智能指针选择,既能享受现代C++带来的便利,又能避免潜在的陷阱。
以上就是C++如何使用unique_ptr管理动态分配对象的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号