dimanche 28 mai 2017

Initialize member istream from either existing istream or from one created by class itself

I'm trying to figure out how I can have a single member variable that either represents a passed in istream or one that the class creates itself.

I figured that using a pointer to the istream could work if I dynamically allocate the istream that the class creates; however, the issue with that is that the unique_ptr will try to free non dynamically allocated memory.

Here's some code that reproduces the issue that I have:

#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 will try to free std::cin, which causes the error. I know I could have use more than one member like

#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");
}

but I'm wondering if there's a way to do it with just one member variable

Aucun commentaire:

Enregistrer un commentaire