提问人:user5280911 提问时间:1/16/2020 更新时间:1/16/2020 访问量:175
在C++中,如何根据运行时条件构造一个引用不同istream对象的对象?
In C++, how to construct an object referencing to different istream object depending on runtime condition?
问:
我想设计一个从文件或控制台读取的对象。如果存在命令行参数,则假定此参数为文件名,代码将从文件中读取。否则,代码将从标准控制台读取。由于 object 和 都是派生自 ,我想在类中存储对 object 或 的引用。以下是该类的代码: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中运行。
答:
2赞
Jarod42
1/16/2020
#1
您可以简单地为以下功能创建一个函数:// 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
}
评论
0赞
bartop
1/16/2020
这将很好地工作,但我认为它给我们带来了明显的代码重复
0赞
Jarod42
1/16/2020
@bartop:只是函数调用是相似的。(我不是说将整个代码复制粘贴到 2 个分支中)。
0赞
bartop
1/16/2020
是的,但是添加新的句柄类型将需要复制粘贴istream
1赞
Aconcagua
1/16/2020
但是,这两种方法并不等价,如果无法打开文件,第一种方法不执行任何操作,第二一种方法用作后备。两者都有效,取决于用户需求,但也许值得强调?std::cin
2赞
Aconcagua
1/16/2020
只是化妆品:我个人宁愿将流作为参考传递,并只在那里创建行阅读器......do_work
评论