在 C++ 中,如何根据运行时条件构造一个引用不同 istream 对象的对象?
In C++, how to construct an object referencing to different istream object depending on runtime condition?
我想设计一个从文件或控制台读取的对象。如果有命令行参数,则假定此参数是文件名,并且代码将从文件中读取。否则,代码将从标准控制台 cin
读取。由于 ifstream
对象和 cin
都派生自 istream
,我想在 class 中存储一个 istream&
对 ifstream
的引用对象或 cin
。下面是 class:
的代码
#include <iostream>
#include <fstream>
#include <sstream>
class Reader {
public:
Reader(std::istream& is) : is(is) {}
private:
std::istream& is;
};
但是我在 运行-time 尝试根据条件创建这样一个对象时遇到了问题。一次尝试如下:
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
对象,但我看不到在条件之前初始化它的方法。我也不知道如何在初始化后 "assign" 对 istream
的引用,因为无法更改引用。另外注意istream
class是不能复制的。如果我想存储对 istream
的引用,并在 运行 时根据条件初始化它,请教我如何编写 Reader
class 好吗?我的想法是处理来自控制台或文件的输入的代码完全相同。我想重用一个变量来表示不同类型的输入流。谢谢。
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
}
我想设计一个从文件或控制台读取的对象。如果有命令行参数,则假定此参数是文件名,并且代码将从文件中读取。否则,代码将从标准控制台 cin
读取。由于 ifstream
对象和 cin
都派生自 istream
,我想在 class 中存储一个 istream&
对 ifstream
的引用对象或 cin
。下面是 class:
#include <iostream>
#include <fstream>
#include <sstream>
class Reader {
public:
Reader(std::istream& is) : is(is) {}
private:
std::istream& is;
};
但是我在 运行-time 尝试根据条件创建这样一个对象时遇到了问题。一次尝试如下:
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
对象,但我看不到在条件之前初始化它的方法。我也不知道如何在初始化后 "assign" 对 istream
的引用,因为无法更改引用。另外注意istream
class是不能复制的。如果我想存储对 istream
的引用,并在 运行 时根据条件初始化它,请教我如何编写 Reader
class 好吗?我的想法是处理来自控制台或文件的输入的代码完全相同。我想重用一个变量来表示不同类型的输入流。谢谢。
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
}