c++ - 从现有 istream 或类本身创建的 istream 初始化成员 istream

标签 c++ file c++11 pointers memory

我试图弄清楚如何拥有一个成员变量,该变量要么代表传入的 istream ,要么代表该类自行创建的成员变量。

我认为,如果我动态分配该类创建的 istream,那么使用指向 istream 的指针就可以工作;但是,问题是 unique_ptr 将尝试释放非动态分配的内存。

这里有一些代码可以重现我遇到的问题:

#include <iostream>
#include <fstream>
#include <memory>
#include <string>

class example {
public:
  explicit example(std::istream& i)
    : m_input(&i)
  {}
  explicit example(const std::string& path)
    : m_input(new std::ifstream(path))
  {}
private:
  std::unique_ptr<std::istream> m_input;
};

int main() {
  example e1(std::cin);
  example e2("./test.txt");
}

e1 将尝试释放 std::cin,这会导致错误。我知道我可以使用多个成员,例如

#include <iostream>
#include <fstream>
#include <memory>
#include <string>

class example {
public:
  explicit example(std::istream& i)
    : m_i(),
      m_input(&i)
  {}
  explicit example(const std::string& path)
    : m_i(path),
      m_input(&m_i)
  {}
private:
  std::ifstream m_i;
  std::istream *m_input;
};

int main() {
  example e1(std::cin);
  example e2("./test.txt");
}

但我想知道是否有一种方法可以只用一个成员变量来做到这一点

最佳答案

我想您可能会通过存储指向流的指针来扩展您的方法:

class X {
    public:
        explicit X(std::istream& stream)
            : stream(&stream, [](std::istream* stream){})
        {}

        explicit X(const std::string& path)
            : stream(new std::ifstream(path),
                [](std::istream* stream) { delete stream; })
        {}

    private:
        using StreamDeleter = std::function<void(std::istream* stream)>;

        std::unique_ptr<std::istream, StreamDeleter> stream;
};

只需添加一个自定义删除器。对于现有流,它不执行任何操作。相反,如果流是手动创建的,则释放该流。

关于c++ - 从现有 istream 或类本身创建的 istream 初始化成员 istream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44230004/

相关文章:

C++11右值引用题

c++ - 如何将tensorflow作为外部依赖项添加到现有的bazel项目中

java - Java 中的父目录

c++ - 将一维数组 reshape 为多维数组

java - 如何使用 Java 创建文件夹(使用 Eclipse Kepler?)?

file - Postgres COPY TO/FROM A FILE 作为非 super 用户

c++ - 为什么成员函数需要 '&'(例如在 std::bind 中)?

c++ - 我试图找到梅森素数

c++ - 检查 vector 项是否不为空 C++

c++ - 针对C++静态销毁/构造订单问题的特定于平台的解决方法