题目

编写程序,演示现代 C++ 独占所有权智能指针 std::unique_ptr。证明其作为原生裸指针的“零额外开销封装”(sizeof(unique_ptr) == sizeof(void*));展示其严禁拷贝(拷贝构造与赋值均被 delete)、仅允许通过 std::move 进行所有权转移(Ownership Transfer)的核心契约;演示自定义删除器(Custom Deleter)释放特殊系统资源的用法。

输入格式:无需外部输入。

输出格式:输出 unique_ptr 构造、所有权转移以及离开作用域自动析构堆对象的全流程。

数据范围与约定:独占所有权模型、移动语义交接、自定义删除器。

思路与算法

1. 独占所有权哲学
同一时刻,有且仅能有一个 std::unique_ptr 拥有目标堆对象的所有权。当该指针离开作用域时,自动调用底层 delete 释放资源。

2. 严禁拷贝与强制移动
尝试 p2 = p1; 会被编译器直接拦截;必须显式写 p2 = std::move(p1);,交接后 p1 被置为空指针 nullptr,所有权完全归属 p2。

3. make_unique 的安全规范
C++14 强烈推荐使用 std::make_unique<T>(args...) 替代裸 new,避免异常抛出时可能造成的内存泄漏并使代码表达更清晰。

完整程序

#include <iostream>
#include <memory>
#include <string>

class Resource {
public:
    std::string name;
    explicit Resource(std::string n) : name(std::move(n)) {
        std::cout << "  [构造 Resource] " << name << "\n";
    }
    ~Resource() {
        std::cout << "  [析构 Resource] " << name << " (自动释放)\n";
    }
    void use() const {
        std::cout << "  [使用 Resource] " << name << " 正常工作中...\n";
    }
};

int main() {
    std::cout << "unique_ptr 实例本身占用栈空间: " << sizeof(std::unique_ptr<Resource>) 
              << " 字节 (严格等于裸指针大小,零额外内存开销)\n\n";

    // 1. 创建独占所有权指针
    std::cout << "--- 1. 使用 std::make_unique 创建对象 ---\n";
    std::unique_ptr<Resource> p1 = std::make_unique<Resource>("AlphaServer");
    p1->use();

    // 2. 所有权转移:移动语义
    std::cout << "\n--- 2. 所有权转移: p2 = std::move(p1) ---\n";
    std::unique_ptr<Resource> p2 = std::move(p1); // p1 放弃所有权

    std::cout << "转移后 p1 是否为 nullptr: " << std::boolalpha << (p1 == nullptr) << "\n";
    std::cout << "转移后 p2 是否有效: " << (p2 != nullptr) << "\n";
    p2->use();

    std::cout << "\n--- 3. 离开作用域,p2 自动析构管理的对象 ---\n";
    return 0;
}

运行示例

输出:

unique_ptr 实例本身占用栈空间: 8 字节 (严格等于裸指针大小,零额外内存开销)

--- 1. 使用 std::make_unique 创建对象 ---
  [构造 Resource] AlphaServer
  [使用 Resource] AlphaServer 正常工作中...

--- 2. 所有权转移: p2 = std::move(p1) ---
转移后 p1 是否为 nullptr: true
转移后 p2 是否有效: true
  [使用 Resource] AlphaServer 正常工作中...

--- 3. 离开作用域,p2 自动析构管理的对象 ---
  [析构 Resource] AlphaServer (自动释放)