c++ - 从函数返回 istream 的正确方法

标签 c++ pointers reference istream

我正在测试从 istream 读取各种数据的技术的速度,因此我创建了一个函数来重复从文件创建 istream,以便下一个测试的方法可以使用该 istream。

using std::istream;
using std::string;

istream* getStreamFrom(string filepath)
{
    std::filebuf init_buffer;
    if (init_buffer.open(filepath, std::ios::in))
    {
        std::istream inputStream(&init_buffer);
        init_buffer.close();
        return &inputStream;
    }

    // file not found
    istream inputStream(0);
    return &inputStream;
}

然后我将 istream 传递给测试方法,如下所示:

istream* data = getStreamFrom(FILEPATH);
someMethod(*data);

但是在 someMethod 中,从 istream 读取时出现访问冲突:

void someMethod(istream& input)
{
    string line;
    while (std::getline(input, line))    // code failes here
        // do something
}

为什么会发生这种情况以及如何解决这个问题?文件是否找到并不重要,两种情况都会发生。

最佳答案

如果要从函数返回本地流,那么您需要动态分配流及其缓冲区。正如注释和答案所解释的那样,您将返回指向局部变量的指针,这些变量将在函数退出后被销毁。标准流类 std::istreamstd::ostream 不可移动,因此您唯一的选择是在堆上创建对象。流和缓冲区都可以包装在智能指针中,以避免手动内存管理。

std::unique_ptr<std::istream> getStreamFrom(std::string filepath) {
  auto init_buf = std::make_unique<std::filebuf>();
  return std::make_unique<std::istream>(
    init_buf->open(filepath, std::ios_base::in)
      ? init_buf.release()->close()
      : nullptr
  );
}

顺便说一句,使用 std::filebuf 初始化的 std::istream 是一个 std::fstream。您也可以返回指向该指针的指针:

std::unique_ptr<std::ifstream> getStreamFrom(std::string filepath) {
  auto stream = std::make_unique<std::ifstream>(filepath);
  stream->close();
  return std::unique_ptr<std::ifstream>( *stream ? std::move(stream) : nullptr );
}

C++17 中可选:

std::optional<std::ifstream> getStreamFrom(std::string filepath) {
  std::ifstream stream(filepath);
  stream.close();
  return stream ? std::optional(std::move(stream)) : std::nullopt;
}

关于c++ - 从函数返回 istream 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59447496/

相关文章:

c++ - c++中的唯一/智能指针 vector

c - 如何在c中比较两个无符号整数(uint8_t)

java - 获取对 java LinkedList 中最近添加的节点的引用

C++ 将对基指针的引用转换为对派生指针的引用

java - JNI - 将 STDOUT 连接到 JTextArea?

c++ - 需要一些帮助来创建一个 cmake 文件以使我的项目正常工作...从 cmake 转换

c++ - C++中如何读取txt文件中的一部分行

c++ - 类型不匹配

java - 更改 Java 动态列表或映射中的对象引用

c++ - 释放 STL vector 中的对象