You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为istream与文件路径实现Doc类初始化构造器的问题

问题描述

我正在编写一个可读取文件或输入内容的Doc类,但在构造器的实现上遇到了困难。需要分别实现接收文件路径和istream对象的构造器,以下是我的代码示例:

main.cc

#include "Doc.h"
#include <cassert>
#include <fstream>  // 原代码中的<stream>为错误引用,需替换为<fstream>
#include <iostream>
#include <string>

using namespace std;

int main() {
    // 从文件读取
    Doc document("romeo.txt");

    // 从流读取
    ofstream("data") << "\r \r  \n\nPeter  \n   Ray\r \n  Egon  \n \n\r\n";
    Doc d("data");
    
    // 测试:打印读取的内容
    d.print();
    return 0;
}

Doc.h

#ifndef DOCUMENT_H
#define DOCUMENT_H

#include <iostream>
#include <string>
#include <vector>

class Doc {
public:
    Doc();                              // 默认构造器
    Doc(const Doc&);                   // 拷贝构造器
    ~Doc();                             // 析构器
    Doc& operator=(const Doc&);        // 赋值运算符

    // 文件路径构造器
    Doc(std::string file_path);              // Doc(path)
    // Istream构造器
    Doc(std::istream& input);                 // Doc(istream)

    // 新增打印方法,用于测试读取结果
    void print() const;

private:
    std::vector<std::string> lines_;  // 存储文档每行内容
};

#endif
构造器实现方案

1. 实现istream构造器

该构造器负责从输入流中逐行读取内容并存储:

#include "Doc.h"
#include <fstream>
#include <string>

// istream构造器实现
Doc::Doc(std::istream& input) {
    std::string line;
    while (std::getline(input, line)) {
        lines_.push_back(line);
    }
}

2. 实现文件路径构造器

通过打开指定文件,复用istream构造器的读取逻辑(推荐用C++11的委托构造简化代码):

// 文件路径构造器实现(C++11及以上支持委托构造)
Doc::Doc(std::string file_path) : Doc(std::ifstream(file_path)) {
    // 检查文件是否成功打开
    auto& file_stream = static_cast<std::ifstream&>(input);
    if (!file_stream.is_open()) {
        std::cerr << "无法打开文件:" << file_path << std::endl;
    }
}

// 若不支持C++11,可改用以下写法:
// Doc::Doc(std::string file_path) {
//     std::ifstream file(file_path);
//     if (!file.is_open()) {
//         std::cerr << "无法打开文件:" << file_path << std::endl;
//         return;
//     }
//     std::string line;
//     while (std::getline(file, line)) {
//         lines_.push_back(line);
//     }
// }

其他成员函数实现

// 默认构造器
Doc::Doc() = default;

// 拷贝构造器
Doc::Doc(const Doc& other) : lines_(other.lines_) {}

// 析构器
Doc::~Doc() = default;

// 赋值运算符
Doc& Doc::operator=(const Doc& other) {
    if (this != &other) {
        lines_ = other.lines_;
    }
    return *this;
}

// 打印方法实现
void Doc::print() const {
    for (const auto& line : lines_) {
        std::cout << line << std::endl;
    }
}
关键注意事项
  • 原main.cc中的<stream>是错误头文件引用,需替换为<fstream>以使用ofstream和ifstream。
  • Doc.h中类定义末尾必须加分号,否则会触发编译错误。
  • 必须处理文件打开失败的情况,避免后续读取操作出现未定义行为。
  • 采用委托构造可大幅减少代码重复,提升可维护性。

内容的提问来源于stack exchange,提问作者Kevin Truong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:20:57