1、 现有智能指针
C++11 标准库中提供的两种智能指针类型std::unique_ptr 和 std::shared_ptr,用于自动管理动态内存,以避免内存泄漏。
1.1 std::unique_ptr
std::unique_ptr拥有独占所有权模型,即每个 std::unique_ptr 只能指向一个对象。当 std::unique_ptr 被销毁时(例如离开作用域或被删除),它会自动删除其指向的对象。std::unique_ptr 可以用于任何类型的对象,包括数组和函数。需要注意的是当创建std::unique_ptr的指针对象只能通过std::move进行指针的赋值,不能用=赋值
std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>(20);
//测试赋值的形式
{
//下面代码在编译时会报C2280错错误
std::unique_ptr<MyClass> uniquePtr2 = uniquePtr;
}
1.2 std::shared_ptr
std::shared_ptr 则允许多个指针指向同一个对象。当最后一个引用该对象的 std::shared_ptr 被销毁时,该对象也会被自动删除。std::shared_ptr 的使用需要引入头文件 <memory>。
这两种智能指针类型都支持一些常见的操作,例如定义指向对象的指针、对指针进行引用、获取指针、交换指针等。它们也都可以用于容器中,例如 map 和 set,以自动管理动态内存。
1.3 示例代码
#include <iostream>
#include <memory>
struct MyClass {
MyClass(int value) : m_value(value) {
std::cout << "Creating MyClass: " << m_value << std::endl;
}
~MyClass() {
std::cout << "Destroying MyClass: " << m_value << std::endl;
}
int m_value;
};
int main() {
std::shared_ptr<MyClass> sharedPtr = std::make_shared<MyClass>(10);
std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>(20);
// 使用 std::shared_ptr
std::cout << "sharedPtr points to object with value: " << sharedPtr->m_value << std::endl;
{
std::shared_ptr<MyClass> tempPtr = sharedPtr; // 共享所有权
std::cout << "tempPtr points to object with value: " << tempPtr->m_value << std::endl;
} // tempPtr 被销毁,不影响 sharedPtr 对对象的所有权
// 使用 std::unique_ptr
std::cout << "uniquePtr points to object with value: " << uniquePtr->m_value << std::endl;
{
std::unique_ptr<MyClass> tempPtr = std::move(uniquePtr); // 转移所有权
std::cout << "tempPtr points to object with value: " << tempPtr->m_value << std::endl;
uniquePtr = nullptr; // uniquePtr 现在不再指向对象,可以安全地置空
} // tempPtr 被销毁,同时转移了所有权给 uniquePtr,现在 uniquePtr 也不再指向对象,可以安全地置空
return 0;
}
2、 历史中的智能指针
std::auto_ptr
std::auto_ptr是C98 标准库中提供的一个简单的智能指针类型,它被设计用来自动管理动态分配的内存,以避免内存泄漏。std::auto_ptr 拥有独占所有权(exclusive ownership)模型,这意味着每个 std::auto_ptr 只能指向一个对象。当 std::auto_ptr 被销毁(例如离开作用域或被删除)时,它会自动删除其指向的对象。然而,std::auto_ptr 在 C11 中已被弃用,并在 C++17 中被删除。取而代之的是更加强大和灵活的智能指针类型,如 std::unique_ptr 和 std::shared_ptr。这些新的智能指针类型提供了更好的所有权管理,并支持自定义删除器和更复杂的场景。因此,建议在新的代码中使用 std::unique_ptr 或 std::shared_ptr 替代 std::auto_ptr。
下面是 std::auto_ptr 的基本使用示例:
--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown
#include <memory>
struct MyClass {
MyClass(int value) : m_value(value) {}
~MyClass() {}
int m_value;
};
void createObject(std::auto_ptr<MyClass> ptr) {
ptr.reset(new MyClass(10)); // 创建新对象
}
int main() {
std::auto_ptr<MyClass> ptr;
createObject(ptr); // 将 ptr 传递给函数,它会在堆上创建一个 MyClass 对象
// 在 createObject 返回后,ptr 现在指向一个 MyClass 对象
// 由于 std::auto_ptr 拥有独占所有权,所以这个对象将在 ptr 被销毁时自动删除
return 0;
}