为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
相关产品推荐
相关产品推荐

