在C ++中,如何根据运行时条件构造引用不同istream对象的对象?

问题描述 投票:1回答:2

我想设计一个从文件或控制台读取的对象。如果有命令行参数,则假定该参数为文件名,并且将从文件中读取代码。否则,将从标准控制台cin中读取代码。由于ifstream对象和cin都是从istream派生的,因此我想在类中存储对istream&对象或ifstreamcin引用。下面是该类的代码:

#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中运行。

c++ c++11 reference initialization iostream
2个回答
0
投票

您可以简单地为// 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
}

-2
投票

您可以执行以下操作:

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.