如何将对象定义为一种类型,然后将其声明为子类型?

时间:2018-03-23 02:07:05

标签: c++ gcc

我有一些需要从istringstream或ifstream读取数据的代码。我对C ++知之甚少,但我在其他语言方面的经验告诉我,我应该只有一个istream变量(ifstream和istringstream的父类型),然后将其设置为istringstream或ifstream。这就是Java中可能会出现的样子:

String word;
IStream stream;

if (someCondition) {
    stream = new IStringStream("banana");
} else {
    stream = new IFStream("apple.txt");
}

while (word = is.read()) {
    // do some stuff
}

这种类型的语法在Java和其他类似语言中没有问题,但我无法在C ++中使用它。这是我的代码现在的样子:

string word;
istream stream;

if (someCondition) {
    string mystr = "banana";
    istringstream stream(mystr);
} else {
    string myfile = "apple.txt";
    ifstream stream(myfile);
}

while(stream >> word) {
    // do some stuff
}

这不能编译,第二行有错误:“没有用于初始化'istream'的匹配构造函数(又名'basic_istream')”。我可以改变什么来使C ++代码像我上面写的Java伪代码一样工作呢?

2 个答案:

答案 0 :(得分:2)

由于你来自Java,一个快速的经验法则是,对于多态对象,你需要一个指针(星号*),一个引用(&符号&),一个智能指针,或者一些其他设置间接的方式。

以下是解决问题的语法示例:

string word;
istream *stream;

if (someCondition) {
    string mystr = "banana";
    stream = new istringstream(mystr);
} else {
    string myfile = "apple.txt";
    stream = new ifstream(myfile);
}

while((*stream) >> word) {
    // do some stuff
}

delete stream;

注意:此解决方案并不理想,因为您最终会手动删除流。更好的方法是依靠智能指针,它会自动删除你的对象。

答案 1 :(得分:2)

你应该将使用流的部分放在一个带std::istream&的函数中,然后传入你想要使用的任何内容。

#include <iostream>
#include <sstream>
#include <fstream>

void useStream(std::istream& stream) {
    std::string word;
    while (stream >> word)
        std::cout << word << ' ';
}

int main() {
    if (someCondition) {
        std::string str = "The best program in the world";
        std::stringstream foo(str);
        useStream(foo);
    }
    else {
        std::ifstream file("text.txt");
        useStream(file);
    }
}