unique_ptr

unique_ptr 是 C++11 引入的智能指针,属于智能指针中的一种,专门用于管理动态分配的内存。它确保所管理的对象在指针超出作用域时会自动销毁,从而避免内存泄漏。与传统的裸指针不同,unique_ptr 提供了更安全和自动化的内存管理机制。

unique_ptr 的基本特性

  1. 唯一所有权unique_ptr 拥有它所指向对象的唯一所有权。当 unique_ptr 被销毁时,它所指向的对象也会被销毁。
  2. 不可复制:由于 unique_ptr 具有唯一所有权,它不能被复制。只能通过移动语义将 unique_ptr 从一个变量转移到另一个变量。
  3. 自动销毁:当 unique_ptr 超出作用域时,它会自动释放所管理的对象,无需手动调用 delete

unique_ptr 的创建与使用

unique_ptr 可以通过 std::make_unique 或直接使用构造函数来创建。

示例:创建和使用 unique_ptr

#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_uniquenew 创建了两个 unique_ptr 对象。unique_ptr 在作用域结束时会自动释放它所管理的内存。

移动语义与 unique_ptr

unique_ptr 不允许复制,但允许转移所有权。使用移动语义,可以将 unique_ptr 从一个变量转移到另一个变量,原来的 unique_ptr 会变为空指针。

示例:移动 unique_ptr

#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() 成员函数来实现这一点。

#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 管理这个新的对象。

#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,可以显著减少内存管理错误,简化代码的内存管理部分,提升程序的安全性与可维护性。