主题
unique_ptr
unique_ptr
是 C++11 引入的智能指针,属于智能指针中的一种,专门用于管理动态分配的内存。它确保所管理的对象在指针超出作用域时会自动销毁,从而避免内存泄漏。与传统的裸指针不同,unique_ptr
提供了更安全和自动化的内存管理机制。
unique_ptr 的基本特性
- 唯一所有权:
unique_ptr
拥有它所指向对象的唯一所有权。当unique_ptr
被销毁时,它所指向的对象也会被销毁。 - 不可复制:由于
unique_ptr
具有唯一所有权,它不能被复制。只能通过移动语义将unique_ptr
从一个变量转移到另一个变量。 - 自动销毁:当
unique_ptr
超出作用域时,它会自动释放所管理的对象,无需手动调用delete
。
unique_ptr 的创建与使用
unique_ptr
可以通过 std::make_unique
或直接使用构造函数来创建。
示例:创建和使用 unique_ptr
cpp
#include <iostream>
#include <memory> // 引入 unique_ptr 所在的头文件
using namespace std;
class MyClass {
public:
MyClass() { cout << "MyClass Constructor\n"; }
~MyClass() { cout << "MyClass Destructor\n"; }
void show() { cout << "Hello, MyClass!\n"; }
};
int main() {
// 使用 make_unique 创建 unique_ptr
unique_ptr<MyClass> ptr1 = make_unique<MyClass>();
ptr1->show(); // 调用 MyClass 的成员函数
// 使用 new 创建 unique_ptr
unique_ptr<MyClass> ptr2(new MyClass());
ptr2->show(); // 调用 MyClass 的成员函数
// unique_ptr 在作用域结束时自动释放内存
return 0;
}
输出:
MyClass Constructor
Hello, MyClass!
MyClass Constructor
Hello, MyClass!
MyClass Destructor
MyClass Destructor
在这个例子中,我们通过 make_unique
和 new
创建了两个 unique_ptr
对象。unique_ptr
在作用域结束时会自动释放它所管理的内存。
移动语义与 unique_ptr
unique_ptr
不允许复制,但允许转移所有权。使用移动语义,可以将 unique_ptr
从一个变量转移到另一个变量,原来的 unique_ptr
会变为空指针。
示例:移动 unique_ptr
cpp
#include <iostream>
#include <memory>
using namespace std;
class MyClass {
public:
MyClass() { cout << "MyClass Constructor\n"; }
~MyClass() { cout << "MyClass Destructor\n"; }
void show() { cout << "Hello, MyClass!\n"; }
};
int main() {
unique_ptr<MyClass> ptr1 = make_unique<MyClass>();
ptr1->show();
// 移动 ptr1 的所有权到 ptr2
unique_ptr<MyClass> ptr2 = move(ptr1);
ptr2->show();
// ptr1 现在为空指针
if (!ptr1) {
cout << "ptr1 is empty\n"; // 输出 ptr1 is empty
}
return 0;
}
输出:
MyClass Constructor
Hello, MyClass!
MyClass Constructor
Hello, MyClass!
ptr1 is empty
MyClass Destructor
MyClass Destructor
在此示例中,ptr1
的所有权被移动到 ptr2
,并且 ptr1
被置为空指针。这样就避免了内存泄漏,同时仍然保证了内存的自动销毁。
unique_ptr 的常见操作
获取裸指针
虽然 unique_ptr
管理内存,但在某些情况下,可能需要获取它所指向对象的裸指针。可以使用 get()
成员函数来实现这一点。
cpp
#include <iostream>
#include <memory>
using namespace std;
class MyClass {
public:
MyClass() { cout << "MyClass Constructor\n"; }
~MyClass() { cout << "MyClass Destructor\n"; }
void show() { cout << "Hello, MyClass!\n"; }
};
int main() {
unique_ptr<MyClass> ptr = make_unique<MyClass>();
// 获取裸指针并使用它
MyClass* rawPtr = ptr.get();
rawPtr->show();
// unique_ptr 会在作用域结束时释放内存
return 0;
}
输出:
MyClass Constructor
Hello, MyClass!
MyClass Destructor
重置 unique_ptr
reset()
方法可以用来重置 unique_ptr
,释放当前管理的对象,并使 unique_ptr
成为一个空指针。如果提供一个新的对象,reset()
会让 unique_ptr
管理这个新的对象。
cpp
#include <iostream>
#include <memory>
using namespace std;
class MyClass {
public:
MyClass() { cout << "MyClass Constructor\n"; }
~MyClass() { cout << "MyClass Destructor\n"; }
void show() { cout << "Hello, MyClass!\n"; }
};
int main() {
unique_ptr<MyClass> ptr = make_unique<MyClass>();
ptr->show();
// 重置 unique_ptr,释放当前对象
ptr.reset();
if (!ptr) {
cout << "ptr is reset and empty\n"; // 输出 ptr is reset and empty
}
return 0;
}
输出:
MyClass Constructor
Hello, MyClass!
ptr is reset and empty
MyClass Destructor
总结
unique_ptr
是 C++11 引入的智能指针,用于管理动态分配的内存。- 它有独占所有权,确保内存的自动释放,避免内存泄漏。
unique_ptr
不能复制,但支持移动语义。unique_ptr
提供了reset()
、get()
等操作,用于管理对象的生命周期。
通过使用 unique_ptr
,可以显著减少内存管理错误,简化代码的内存管理部分,提升程序的安全性与可维护性。