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

C++ 从现有istream或从类本身创建的istream初始化成员istream,c++,file,c++11,pointers,memory,C++,File,C++11,Pointers,Memory,我正试图弄清楚如何使用单个成员变量来表示传入的istream,或者类自己创建的变量 我想,如果我动态分配类创建的istream,那么使用指向istream的指针可以工作;但是,问题是unique_ptr将尝试释放非动态分配的内存 这里有一些代码重现了我遇到的问题: #include <iostream> #include <fstream> #include <memory> #include <string> class example { p

我正试图弄清楚如何使用单个成员变量来表示传入的
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");
}

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

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

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;
};
X类{
公众:
显式X(标准::istream&stream)
:stream(&stream,[](std::istream*stream){})
{}
显式X(常量std::字符串和路径)
:流(新标准::ifstream(路径),
[](std::istream*流){删除流;})
{}
私人:
使用StreamDeleter=std::函数;
std::唯一的ptr流;
};

只需添加一个自定义删除程序。在现有流的情况下,它什么也不做。相反,如果流是手动创建的,它会释放流。

流不可复制吗?你的问题中我遗漏了什么吗?@πάνταῥεῖ 对,它们是不可复制的,所以我需要一个作为指针的成员或对传入流的引用。但是,这与我创建自己的流的构造函数冲突,因为如果我想使用相同的成员变量(指针),我必须动态分配。这样做的问题是,我只在字符串构造函数中动态分配指针,因此,当我尝试取消分配时,如果
示例
是从现有的
istream
构造的,那么这将是一个错误。有意义吗?不,那东西没有意义,对不起。请详细说明您的用例和您实际想要解决的问题。@πάνταῥεῖ 好吧,对不起,我不清楚。我有一个需要从输入流读取的类。我的目标是,我希望能够从现有的输入流或文件路径初始化该类的输入流?如果只是为了方便起见,我会删除它以保持接口和实现的简单。类
example
的用户已经可以创建一个
std::ifstream
(可以从文件路径构造)并将其传递给类
example
。我正准备回答这个问题+谢谢!既然你已经回答了我的假设性问题,是否可以这样做,你认为我应该这样做吗?与只有一个额外的成员相比,它似乎相当复杂。@AR7我想添加一个额外的成员不是最好的选择。使用自定义删除器,您可能有一个更灵活的解决方案。我的意思是,为不同的情况添加新成员会使设计非常尴尬。同时,您可能会避免使用它,并且只有一个成员知道如何正确地释放资源(流)。
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;
};