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

时间:2017-05-28 17:17:47

标签: 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");
}

但我想知道是否有办法只用一个成员变量

1 个答案:

答案 0 :(得分:3)

我猜你可以通过存储指向流的指针来扩展你的方法:

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;
};

只需添加自定义删除工具即可。在现有流的情况下,它什么都不做。相反,如果手动创建流,则会释放流。