我想设计一个从文件或控制台读取的对象。如果有命令行参数,则假定该参数为文件名,并且将从文件中读取代码。否则,将从标准控制台cin
中读取代码。由于ifstream
对象和cin
都是从istream
派生的,因此我想在类中存储对istream&
对象或ifstream
的cin
引用。下面是该类的代码:
#include <iostream>
#include <fstream>
#include <sstream>
class Reader {
public:
Reader(std::istream& is) : is(is) {}
private:
std::istream& is;
};
但是在运行时根据条件尝试创建这样的对象时遇到了问题。尝试如下:
int main(int argc, char *argv[]) {
if (argc > 1) { //read from file
std::ifstream in_f(argv[1]);
if (in_f)
LineReader reader(in_f);
}
else { //read from console (standard input)
LineReader reader(std::cin);
}
//work on reader ...
return 0;
}
事实是,Reader
对象是在条件语句中构造的。执行结束后,它将消失。但是我需要这个对象在构造之后要做很多工作。因此,我应该在条件之外定义一个Reader
对象,但是看不到在条件之前对其进行初始化的任何方法。我也不清楚初始化后如何“分配”对istream
的引用,因为无法更改引用。另外请注意,不能复制istream
类。因此,如果我想存储对Reader
的引用,并在运行时根据条件对其进行初始化,您能否教我如何编写istream
类?我的想法是,用于处理来自控制台或文件的输入的代码完全相同。我想重用一个变量来表示不同类型的输入流。谢谢。
PS:我正在使用C ++ 11,该代码将在Windows和Ubuntu中运行。
您可以简单地为// work on reader
创建一个函数:
void do_work(LineReader& reader)
{
// work on reader
}
int main(int argc, char *argv[]) {
if (argc > 1) { //read from file
std::ifstream in_f(argv[1]);
if (in_f) {
LineReader reader(in_f);
do_work(reader);
}
}
else { //read from console (standard input)
LineReader reader(std::cin);
do_work(reader);
}
}
或重新组织代码以获得对std::istream
的引用:
std::istream& get_istream(std::ifstream& in_f, int argc, char* argv[])
{
if (argc > 1) { //read from file
in_f.open(argv[1]);
}
if (in_f) {
return in_f;
} else {
return std::cin;
}
}
int main(int argc, char *argv[]) {
std::ifstream in_f;
LineReader reader(get_istream(in_f, argc, argv));
// work on reader
}
您可以执行以下操作:
int main(int argc, char *argv[]) {
LineReader * lpLineReader = NULL;
if (argc > 1) { //read from file
std::ifstream in_f(argv[1]);
if (in_f)
lpLineReader = new LineReader(in_f);
}
else { //read from console (standard input)
lpLineReader = new LineReader(std::cin);
}
//work on reader ...
delete lpLineReader
return 0;
}