站点回复管理系统

以下实现了一个基于 std::vector 派生的 SiteReplies 类,结合内存分配(alloc())、对象管理、生命周期控制、序列化/反序列化、异常处理等功能,覆盖实际开发中常见的场景。

1. 完整代码实现
cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <stdexcept>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <ctime>

// 前置声明
class ResponseMessage;
class SiteReplies;

// 回复消息类:表示站点的一条回复
class ResponseMessage {
private:
    std::string id;          // 回复唯一ID
    std::string content;     // 回复内容
    std::string author;      // 回复作者
    time_t createTime;       // 创建时间
    bool isPublished;        // 是否发布

public:
    // 构造函数
    ResponseMessage(const std::string& id_, const std::string& content_, 
                   const std::string& author_, bool published = false)
        : id(id_), content(content_), author(author_), isPublished(published) {
        createTime = time(nullptr); // 默认当前时间
    }

    // 析构函数
    ~ResponseMessage() {
        std::cout << "[销毁] 回复ID: " << id << std::endl;
    }

    // 拷贝构造(禁用,避免浅拷贝)
    ResponseMessage(const ResponseMessage&) = delete;
    ResponseMessage& operator=(const ResponseMessage&) = delete;

    // 移动构造
    ResponseMessage(ResponseMessage&& other) noexcept {
        id = std::move(other.id);
        content = std::move(other.content);
        author = std::move(other.author);
        createTime = other.createTime;
        isPublished = other.isPublished;
        other.createTime = 0;
    }

    // 成员方法
    void publish() { isPublished = true; }
    void editContent(const std::string& newContent) { content = newContent; }
    
    // 获取器
    std::string getId() const { return id; }
    std::string getContent() const { return content; }
    std::string getAuthor() const { return author; }
    time_t getCreateTime() const { return createTime; }
    bool getIsPublished() const { return isPublished; }

    // 序列化:将对象转为字符串(用于存储/传输)
    std::string serialize() const {
        std::ostringstream oss;
        oss << id << "|" << content << "|" << author << "|" 
            << createTime << "|" << (isPublished ? "1" : "0");
        return oss.str();
    }

    // 反序列化:从字符串重建对象
    static ResponseMessage* deserialize(const std::string& data) {
        std::istringstream iss(data);
        std::string id, content, author, createTimeStr, publishedStr;
        
        if (!std::getline(iss, id, '|') || !std::getline(iss, content, '|') ||
            !std::getline(iss, author, '|') || !std::getline(iss, createTimeStr, '|') ||
            !std::getline(iss, publishedStr, '|')) {
            throw std::invalid_argument("反序列化失败:数据格式错误");
        }

        time_t createTime = std::stoll(createTimeStr);
        bool isPublished = (publishedStr == "1");
        return new ResponseMessage(id, content, author, isPublished);
    }
};

// 站点回复容器:继承std::vector<ResponseMessage*>,扩展业务逻辑
class SiteReplies : public std::vector<ResponseMessage*> {
private:
    std::string siteId; // 所属站点ID
    size_t maxCapacity; // 最大容量

public:
    // 构造函数
    SiteReplies(const std::string& siteId_, size_t maxCap = 1000)
        : siteId(siteId_), maxCapacity(maxCap) {}

    // 析构函数:释放所有回复对象
    ~SiteReplies() {
        clearReplies();
        std::cout << "[销毁] 站点" << siteId << "的回复容器" << std::endl;
    }

    // 禁用拷贝(避免浅拷贝导致重复释放)
    SiteReplies(const SiteReplies&) = delete;
    SiteReplies& operator=(const SiteReplies&) = delete;

    // 移动构造
    SiteReplies(SiteReplies&& other) noexcept 
        : std::vector<ResponseMessage*>(std::move(other)),
          siteId(std::move(other.siteId)),
          maxCapacity(other.maxCapacity) {
        other.maxCapacity = 0;
    }

    // 核心方法:分配新回复(内存分配+容器添加)
    ResponseMessage* alloc(const std::string& replyId, 
                          const std::string& content, 
                          const std::string& author) {
        // 容量检查
        if (size() >= maxCapacity) {
            throw std::overflow_error("回复容器已达最大容量:" + std::to_string(maxCapacity));
        }

        // 检查ID唯一性
        if (findReplyById(replyId) != nullptr) {
            throw std::invalid_argument("回复ID已存在:" + replyId);
        }

        // 分配内存并添加到容器
        ResponseMessage* newReply = new ResponseMessage(replyId, content, author);
        push_back(newReply);
        std::cout << "[分配] 新增回复ID:" << replyId << " 站点:" << siteId << std::endl;
        return newReply;
    }

    // 根据ID查找回复
    ResponseMessage* findReplyById(const std::string& replyId) const {
        auto it = std::find_if(begin(), end(), [&](const ResponseMessage* msg) {
            return msg->getId() == replyId;
        });
        return (it != end()) ? *it : nullptr;
    }

    // 发布指定ID的回复
    bool publishReply(const std::string& replyId) {
        ResponseMessage* reply = findReplyById(replyId);
        if (reply) {
            reply->publish();
            std::cout << "[发布] 回复ID:" << replyId << std::endl;
            return true;
        }
        return false;
    }

    // 批量发布作者的所有回复
    size_t publishRepliesByAuthor(const std::string& author) {
        size_t count = 0;
        for (auto* reply : *this) {
            if (reply->getAuthor() == author && !reply->getIsPublished()) {
                reply->publish();
                count++;
            }
        }
        std::cout << "[批量发布] 作者" << author << "的" << count << "条回复" << std::endl;
        return count;
    }

    // 清空所有回复(释放内存)
    void clearReplies() {
        for (auto* reply : *this) {
            delete reply; // 释放单个回复
        }
        clear(); // 清空vector
        std::cout << "[清空] 站点" << siteId << "的所有回复" << std::endl;
    }

    // 导出回复到文件
    bool exportToFile(const std::string& filename) const {
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }

        file << "站点ID:" << siteId << "\n";
        file << "回复总数:" << size() << "\n";
        for (const auto* reply : *this) {
            file << reply->serialize() << "\n";
        }
        file.close();
        std::cout << "[导出] 站点" << siteId << "的" << size() << "条回复到" << filename << std::endl;
        return true;
    }

    // 从文件导入回复
    size_t importFromFile(const std::string& filename) {
        std::ifstream file(filename);
        if (!file.is_open()) {
            throw std::runtime_error("无法打开文件:" + filename);
        }

        std::string line;
        // 跳过站点ID行
        std::getline(file, line);
        // 跳过回复总数行
        std::getline(file, line);

        size_t imported = 0;
        while (std::getline(file, line) && !line.empty()) {
            try {
                ResponseMessage* reply = ResponseMessage::deserialize(line);
                // 检查容量和ID唯一性
                if (size() >= maxCapacity) break;
                if (findReplyById(reply->getId()) == nullptr) {
                    push_back(reply);
                    imported++;
                } else {
                    delete reply; // 重复ID,释放内存
                }
            } catch (const std::exception& e) {
                std::cerr << "[导入失败] " << e.what() << std::endl;
            }
        }
        file.close();
        std::cout << "[导入] 站点" << siteId << "成功导入" << imported << "条回复" << std::endl;
        return imported;
    }

    // 获取站点ID
    std::string getSiteId() const { return siteId; }

    // 获取容量信息
    size_t getMaxCapacity() const { return maxCapacity; }
    size_t getUsedCapacity() const { return size(); }
};

// 辅助函数:打印回复详情
void printReplyInfo(const ResponseMessage* reply) {
    if (!reply) {
        std::cout << "回复不存在" << std::endl;
        return;
    }
    std::cout << "------------------------" << std::endl;
    std::cout << "回复ID: " << reply->getId() << std::endl;
    std::cout << "内容: " << reply->getContent() << std::endl;
    std::cout << "作者: " << reply->getAuthor() << std::endl;
	  // 第一步:将返回值赋值给局部变量(左值)
	  time_t createTime = reply->getCreateTime();
	  // 第二步:对左值取地址传入ctime
	  std::cout << "创建时间: " << ctime(&createTime);
    std::cout << "发布状态: " << (reply->getIsPublished() ? "已发布" : "未发布") << std::endl;
    std::cout << "------------------------" << std::endl;
}

// 主函数:演示完整使用流程
int main() {
    try {
        // 1. 创建站点回复容器(站点ID: blog_001,最大容量5)
        SiteReplies siteReplies("blog_001", 5);
        std::cout << "=== 初始化站点" << siteReplies.getSiteId() << "的回复容器 ===" << std::endl;
        std::cout << "最大容量: " << siteReplies.getMaxCapacity() << std::endl;

        // 2. 分配新回复
        ResponseMessage* r1 = siteReplies.alloc("r001", "这是第一条回复", "user_001");
        ResponseMessage* r2 = siteReplies.alloc("r002", "C++真好用", "user_002");
        ResponseMessage* r3 = siteReplies.alloc("r003", "继承vector要注意内存管理", "user_001");

        // 3. 打印回复详情
        std::cout << "\n=== 打印r002详情 ===" << std::endl;
        printReplyInfo(r2);

        // 4. 编辑回复内容
        r2->editContent("C++容器扩展真灵活");
        std::cout << "\n=== 编辑后r002详情 ===" << std::endl;
        printReplyInfo(r2);

        // 5. 发布回复
        std::cout << "\n=== 发布回复 ===" << std::endl;
        siteReplies.publishReply("r001");
        siteReplies.publishRepliesByAuthor("user_001");

        // 6. 查找回复
        std::cout << "\n=== 查找回复r003 ===" << std::endl;
        printReplyInfo(siteReplies.findReplyById("r003"));

        // 7. 导出回复到文件
        std::cout << "\n=== 导出回复 ===" << std::endl;
        if (!siteReplies.exportToFile("replies_blog_001.txt")) {
            std::cerr << "导出文件失败" << std::endl;
        }

        // 8. 测试容量限制(故意触发异常)
        std::cout << "\n=== 测试容量限制 ===" << std::endl;
        siteReplies.alloc("r004", "第四条回复", "user_003");
        siteReplies.alloc("r005", "第五条回复", "user_004");
        try {
            siteReplies.alloc("r006", "第六条回复", "user_005"); // 超出容量
        } catch (const std::overflow_error& e) {
            std::cerr << "捕获异常: " << e.what() << std::endl;
        }

        // 9. 导入回复(演示)
        std::cout << "\n=== 导入回复 ===" << std::endl;
        SiteReplies newSite("blog_002");
        newSite.importFromFile("replies_blog_001.txt");

        // 10. 清空回复
        std::cout << "\n=== 清空回复 ===" << std::endl;
        siteReplies.clearReplies();

    } catch (const std::exception& e) {
        std::cerr << "程序异常: " << e.what() << std::endl;
        return 1;
    }

    std::cout << "\n=== 程序正常结束 ===" << std::endl;
    return 0;
}
2. 核心功能说明
功能模块 实现要点
内存管理 alloc() 方法负责分配 ResponseMessage 对象并加入容器,析构函数/clearReplies() 释放所有对象,避免内存泄漏
容器扩展 继承 std::vector<ResponseMessage*> 并扩展业务方法(查找、发布、导入导出等)
数据校验 分配回复时检查容量限制、ID唯一性,避免非法数据
序列化/反序列化 支持回复对象与字符串的互转,实现持久化(文件导入导出)
异常处理 捕获容量溢出、ID重复、文件操作失败等异常,保证程序健壮性
生命周期控制 禁用拷贝构造,使用移动构造避免浅拷贝问题,明确对象所有权
3. 编译与运行
  • 编译命令(g++):g++ -std=c++17 site_replies.cpp -o site_replies
  • 运行:./site_replies
  • 运行后会生成 replies_blog_001.txt 文件,包含回复的序列化数据
相关推荐
im_AMBER2 小时前
Leetcode 83 使数组平衡的最少移除数目中等相关标签 | 尽可能使字符串相等
数据结构·c++·笔记·学习·算法·leetcode
XFF不秃头2 小时前
力扣刷题笔记-组合总和
c++·笔记·leetcode
xu_yule2 小时前
算法基础(图论)—拓扑排序
c++·算法·动态规划·图论·拓扑排序·aov网
R&L_201810012 小时前
C++之constexpr 编译时计算
c++·c++新特性·c++ 新特性
我是华为OD~HR~栗栗呀2 小时前
(华为od)21届-Python面经
java·前端·c++·python·华为od·华为·面试
kyle~2 小时前
导航---Nav2导航框架概览
c++·机器人·ros2·导航
DolphinDB智臾科技2 小时前
如何用脚本榨出C++级性能?微秒级低延时系统优化深度解析
大数据·c++·时序数据库·低延时·dolphindb
小龙报3 小时前
【初阶数据结构】从 “数组升级” 到工程实现:动态顺序表实现框架的硬核拆解指南
c语言·数据结构·c++·算法·机器学习·信息与通信·visual studio
我不是8神3 小时前
序列化与反序列化详解
c++