基于C++ Question与Quiz类将题目加载至私有vector的语法疑问
一步步实现:将Question存入Quiz的私有vector里
没问题,我来帮你搞定这个需求,下面是具体的代码实现和关键要点说明:
1. 先定义Question类
首先我们需要一个能存储题目信息的Question类,包含题型、题号、问题文本和答案这些字段,再配上构造函数和必要的getter方法:
#include <string> #include <vector> #include <fstream> #include <sstream> #include <iostream> #include <stdexcept> // 定义Question类,封装题目信息 class Question { private: std::string type; // 比如示例中的"S"(单选题) int id; // 题目编号 std::string questionText; // 问题内容 std::string answer; // 正确答案 public: // 构造函数:用解析后的字段初始化Question对象 Question(std::string t, int i, std::string q, std::string a) : type(std::move(t)), id(i), questionText(std::move(q)), answer(std::move(a)) {} // Getter方法:允许外部(比如Quiz类)安全访问私有成员 const std::string& getType() const { return type; } int getId() const { return id; } const std::string& getQuestionText() const { return questionText; } const std::string& getAnswer() const { return answer; } };
2. 实现Quiz类(包含私有Question向量)
接下来是核心的Quiz类,我们把存储题目的vector<Question>放在私有区域,再实现读取文件、解析题目的成员函数:
class Quiz { private: // 私有成员:仅Quiz类能直接操作的题目容器 std::vector<Question> questions; // 辅助函数:解析单行文本为Question对象 Question parseQuestionLine(const std::string& line) { std::stringstream lineStream(line); std::string type, idStr, question, answer; // 按|分割字段,注意处理可能的格式错误 if (!std::getline(lineStream, type, '|') || !std::getline(lineStream, idStr, '|') || !std::getline(lineStream, question, '|') || !std::getline(lineStream, answer, '|')) { throw std::invalid_argument("题目行格式错误: " + line); } // 把题号字符串转为整数,处理转换失败的情况 int id; try { id = std::stoi(idStr); } catch (const std::exception& e) { throw std::invalid_argument("题号格式错误: " + idStr); } return Question(type, id, question, answer); } public: // 从指定文件加载题目到私有vector bool loadQuestions(const std::string& filename) { std::ifstream file(filename); if (!file.is_open()) { std::cerr << "错误:无法打开文件 " << filename << std::endl; return false; } std::string line; int lineNum = 0; while (std::getline(file, line)) { lineNum++; // 跳过空行 if (line.empty()) continue; try { Question q = parseQuestionLine(line); questions.push_back(std::move(q)); // 用move提升效率 } catch (const std::exception& e) { std::cerr << "第" << lineNum << "行解析失败: " << e.what() << std::endl; // 可以选择继续加载其他题目,或者直接返回失败 // return false; } } file.close(); std::cout << "成功加载 " << questions.size() << " 道有效题目" << std::endl; return true; } // 示例方法:打印所有题目,验证加载结果 void printAllQuestions() const { for (const auto& q : questions) { std::cout << "[" << q.getId() << "] " << q.getQuestionText() << std::endl; std::cout << "正确答案: " << q.getAnswer() << "\n" << std::endl; } } };
3. 使用示例(主函数)
最后在主函数里调用Quiz的方法,完成题目加载:
int main() { Quiz myQuiz; if (myQuiz.loadQuestions("questions.txt")) { myQuiz.printAllQuestions(); } return 0; }
关键语法与操作说明
- 私有vector的声明:在
Quiz的private块里写std::vector<Question> questions;,这样就把题目容器封装在Quiz内部,符合面向对象的封装原则,外部无法直接修改,只能通过Quiz提供的方法操作。 - 解析文件行:用
std::stringstream配合std::getline按|分割每一行的字段,同时添加了错误处理,避免格式错误的行导致程序崩溃。 - 填充vector:解析出Question对象后,用
questions.push_back()(或者emplace_back()更高效)把对象添加到私有容器里,示例里用了std::move减少拷贝开销。 - 访问控制:通过Question类的public getter方法,Quiz可以安全访问题目内容,同时保证Question的私有成员不会被外部随意修改。
额外注意点
- 如果你的题目文件有更复杂的格式(比如多选题有多个答案),可以扩展Question类的成员变量,比如用
std::vector<std::string>存储多个答案。 - 可以给Quiz类添加更多方法,比如根据题号查找题目、随机抽取题目等,都是基于这个私有vector来操作的。
内容的提问来源于stack exchange,提问作者StevenSchulze
相关产品推荐
相关产品推荐

