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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将对象定义为一种类型,然后将其声明为子类型?相关的知识,希望对你有一定的参考价值。

我有一些代码需要从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伪代码一样工作?

答案

由于你来自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);
    }
}

以上是关于如何将对象定义为一种类型,然后将其声明为子类型?的主要内容,如果未能解决你的问题,请参考以下文章

将两个文件分组为一种自定义文件类型

1如何声明一个类?如何创建类的对象?

Typescript:如何声明一种值等于对象键的数组类型?

声明泛型类型的 const

C++将模板的声明和定义放置在同一个头文件里

如何在 C# 中将列表或数组转换为子类型?