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

How can I define an object as one type, then later declare it as a sub-type?

本文关键字:类型 然后 声明 一种 对象 定义      更新时间:2023-10-16

我有一些代码需要从 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
}

这不会编译,第 2 行出现错误:"没有用于初始化 'istream'(又名'basic_istream'(的匹配构造函数"。我可以更改哪些内容以使C++代码像我上面编写的 Java 伪代码示例一样工作?

由于您来自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;

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

您应该将使用

流的部分放在一个接受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);
    }
}
相关文章: