ostream: class that outputs either on cout or on a file

后端 未结 2 1059
天命终不由人
天命终不由人 2021-01-24 02:38

I need to write a program that output either to the std::cout or to some file. I was reading this post to see how to do. However I would like to separate the manage

2条回答
  •  一个人的身影
    2021-01-24 02:59

    I would try to split here the stream creation with the stream usage. std::ostream is already polymorphic, so as long as you pass a reference or pointer to the function that uses the stream, all good.

    For the creation, I would go for creating the stream in the heap, as the post you linked to suggests. However, doing explicit memory management (raw new/delete) is dangerous, so I would use a smart pointer, like std::unique_ptr:

    #include 
    #include 
    
    struct ConditionalDeleter
    {
        bool must_delete;
        void operator()(std::ostream* os) const { if (must_delete) delete os; }
    };
    
    using OstreamPtr = std::unique_ptr;
    
    OstreamPtr create_stream(bool to_file)
    {
        if (to_file)
            return OstreamPtr { new std::ofstream {"myfile.txt"}, ConditionalDeleter {true} };
        else
            return OstreamPtr { &std::cout, ConditionalDeleter {false} };
    }
    
    void use_stream(std::ostream& os)
    {
        os << "Hello world!" << std::endl;
    }
    
    int main()
    {
        auto streamptr = create_stream(false);
        use_stream(*streamptr);
    }
    

    I've used a custom deleter with std::unique_ptr. The reason for that is: if we are using the file, I want the stream to be deleted; but std::cout is a global object, which we must not delete. The agreement here is that when your OstreamPtr gets destroyed, ConditionalDeleter::operator() will get called. *streamptr returns you a reference to your std::ostream, which you can use as you want.

    Please note you need C++11 support to use this solution.

提交回复
热议问题