#include <cstdio>
#include <iostream>
#include <utility>

class FileHandle {
    std::FILE* file_;
    std::string path_;

  public:
    explicit FileHandle(const char* path, const char* mode)
        : file_(std::fopen(path, mode)), path_(path) {
        if (!file_) {
            throw std::runtime_error("Failed to open file: " + path_);
        }
    }

    ~FileHandle() {
        if (file_) {
            std::fclose(file_);
            std::cout << "  关闭文件: " << path_ << "\n";
        }
    }

    // 禁止拷贝——文件句柄不可共享
    FileHandle(const FileHandle&) = delete;
    FileHandle& operator=(const FileHandle&) = delete;

    // 允许移动——文件句柄可以转移所有权
    FileHandle(FileHandle&& other) noexcept : file_(other.file_), path_(std::move(other.path_)) {
        other.file_ = nullptr; // 防止 other 析构时关闭文件
    }

    FileHandle& operator=(FileHandle&& other) noexcept {
        if (this != &other) {
            if (file_) {
                std::fclose(file_); // 关闭当前文件
            }
            file_ = other.file_;
            path_ = std::move(other.path_);
            other.file_ = nullptr;
        }
        return *this;
    }

    std::FILE* get() const { return file_; }
    const std::string& path() const { return path_; }
};

/// @brief 工厂函数：打开日志文件
FileHandle open_log(const std::string& name) {
    return FileHandle(name.c_str(), "a");
}

int main() {
    auto log = open_log("app.log");
    std::fprintf(log.get(), "Application started\n");

    // 把日志文件的所有权转移给另一个变量
    FileHandle moved_log = std::move(log);
    std::fprintf(moved_log.get(), "Log handle moved\n");

    // log.get() 现在返回 nullptr，不要再使用它
    return 0;
}
