C++ 类输出到多个ostream(文件和控制台)

C++ 类输出到多个ostream(文件和控制台),c++,inheritance,ostream,C++,Inheritance,Ostream,对,我甚至不知道如何正确表述,;我觉得这是一个有点复杂的问题。不过我相信有人能帮我 这就是我想做的: 有一个单独的类,我可以发送东西到,像这样 icl << "Blah blah blah" << std::endl; icl您可能需要这样的东西: class OutputMan { std::vector<std::ostream*> m_Streams; public: void attach(std::ostream *os) {

对,我甚至不知道如何正确表述,;我觉得这是一个有点复杂的问题。不过我相信有人能帮我

这就是我想做的:

  • 有一个单独的类,我可以发送东西到,像这样

    icl << "Blah blah blah" << std::endl;
    

    icl您可能需要这样的东西:

    class OutputMan {
        std::vector<std::ostream*> m_Streams;
    
    public:
        void attach(std::ostream *os) {
            m_Streams.push_back(os);
        }
    
        template <typename T>
        OutputMan &operator<<(const T &t) {
    
            for (int i=0; i<m_Streams.size(); i++)
                *m_Streams[i] << t;
    
            return *this;
        }
    };
    
    int main() {
        ofstream file("test.txt");
    
        OutputMan x;
        x.attach(&cout);
        x.attach(&cerr);
        x.attach(&file);
    
        x << "Hello" << 123;
    }
    
    classoutputman{
    std::向量m_流;
    公众:
    无效附加(标准::ostream*os){
    m_流。推回(os);
    }
    模板
    
    OutputMan&operator我想我会做一些不同的事情。我可能已经把这件事做得比必要的更详细了一点——我担心我可能会因为试图充分利用新的C++11功能而有点忘乎所以。无论如何,继续代码:

    #include <streambuf>
    #include <fstream>
    #include <vector>
    #include <iostream>
    #include <initializer_list>
    
    namespace multi { 
    class buf: public std::streambuf {
        std::vector<std::streambuf *> buffers;
    public:
        typedef std::char_traits<char> traits_type;
        typedef traits_type::int_type  int_type;
    
        buf(std::vector<std::ofstream> &buf) {
            for (std::ofstream &os : buf)
                buffers.push_back(os.rdbuf());
        }
    
        void attach(std::streambuf *b) { buffers.push_back(b); }
    
        int_type overflow(int_type c) {
            bool eof = false;
            for (std::streambuf *buf : buffers) 
                eof |= (buf -> sputc(c) == traits_type::eof());
            return eof ? traits_type::eof() : c;
        }   
    };
    
    class stream : public std::ostream { 
        std::vector<std::ofstream> streams;
        buf outputs;
    public:   
        stream(std::initializer_list<std::string> names)
            : streams(names.begin(), names.end()), 
              outputs(streams), 
              std::ostream(&outputs) 
        { }
        void attach(std::ostream &b) {
            outputs.attach(b.rdbuf());
        }
    };
    }
    
    int main() { 
        multi::stream icl({"c:\\out1.txt", "c:\\out2.txt"});
        icl.attach(std::cout);
    
        icl << "Blah blah blah" << std::endl;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    命名空间多{
    buf类:公共标准::streambuf{
    向量缓冲器;
    公众:
    typedef std::char_traits_type;
    typedef traits_type::int_type int_type;
    buf(标准::向量和buf){
    用于(标准::ofstream&os:buf)
    buffers.push_back(os.rdbuf());
    }
    void attach(std::streambuf*b){buffers.push_back(b);}
    int_类型溢出(int_类型c){
    bool-eof=false;
    用于(std::streambuf*buf:buffers)
    eof |=(buf->sputc(c)=特征类型::eof();
    返回eof?traits_type::eof():c;
    }   
    };
    类流:public std::ostream{
    std::矢量流;
    buf输出;
    公众:
    流(std::初始值设定项\列表名称)
    :streams(names.begin()、names.end()),
    输出(流),
    std::ostream(输出和输出)
    { }
    无效附加(标准::ostream&b){
    outputs.attach(b.rdbuf());
    }
    };
    }
    int main(){
    多::流icl({“c:\\out1.txt”,“c:\\out2.txt”});
    icl.附件(标准::cout);
    
    icl问题#1:Google操作符重载,你会看到很多例子。我很清楚操作符重载是如何工作的,但这里似乎有点复杂,因为有大量的数据类型可以像整数一样输入OutputMan。当然有更好的方法。你可以使用一个带有特定模板o的模板可能需要特殊处理的类型的重载/实例化(不确定其名称)。您是否也清楚指针或数组上的语言限制(在本例中,
    std::vector
    在某种程度上是两者兼而有之)在你设计的时候,你可能想考虑这个问题。因为OutputMan本身就是一个输出流,它要么继承一个,要么提供一个定制的<代码> StRuBF来调度输出。这就是我想要的。有点让问题#2未获解答,但这至少是向前迈出了一大步。@JesseBrands:是的,有可能,再次看到我更新的答案。非常感谢,你帮了我很大的忙。还有一个问题,如果我制作了一个派生自std::ostream的类,它OutputMan也会接受吗?我想是的。是的,它可以。不管派生自STL不推荐。我将不得不接受这个答案;非常详细,真的让我达到了我想要的目的。非常感谢!PS:如果你在某个时候更新了答案,一定要让我知道。我非常好奇这将如何工作。但是有一个问题。我不能使用C++11来完成这个项目,所以我使用boost/foreach.hpp来完成这个项目但是,我不能这样做:
    Mage::IO::MultiStream ICL({“Mage3D.log”,“Game.log”})<代码> > STD::IXILALIZERILIListEng/<代码> C++ 11之前的C++部分?@ JeSSBrand:对不起。<代码> STD::IXPRIALIZELSYLISTRON/<代码>也是C++的新版本,我已经调整了代码,与您的结果相同。谢谢您的出色回答。
    
    class OutputMan {
        std::vector<std::ostream*> m_Streams;
    
    public:
        void attach(std::ostream *os) {
            m_Streams.push_back(os);
        }
    
        template <typename T>
        OutputMan &operator<<(const T &t) {
    
            for (int i=0; i<m_Streams.size(); i++)
                *m_Streams[i] << t;
    
            return *this;
        }
    };
    
    int main() {
        ofstream file("test.txt");
    
        OutputMan x;
        x.attach(&cout);
        x.attach(&cerr);
        x.attach(&file);
    
        x << "Hello" << 123;
    }
    
    #include <streambuf>
    #include <fstream>
    #include <vector>
    #include <iostream>
    #include <initializer_list>
    
    namespace multi { 
    class buf: public std::streambuf {
        std::vector<std::streambuf *> buffers;
    public:
        typedef std::char_traits<char> traits_type;
        typedef traits_type::int_type  int_type;
    
        buf(std::vector<std::ofstream> &buf) {
            for (std::ofstream &os : buf)
                buffers.push_back(os.rdbuf());
        }
    
        void attach(std::streambuf *b) { buffers.push_back(b); }
    
        int_type overflow(int_type c) {
            bool eof = false;
            for (std::streambuf *buf : buffers) 
                eof |= (buf -> sputc(c) == traits_type::eof());
            return eof ? traits_type::eof() : c;
        }   
    };
    
    class stream : public std::ostream { 
        std::vector<std::ofstream> streams;
        buf outputs;
    public:   
        stream(std::initializer_list<std::string> names)
            : streams(names.begin(), names.end()), 
              outputs(streams), 
              std::ostream(&outputs) 
        { }
        void attach(std::ostream &b) {
            outputs.attach(b.rdbuf());
        }
    };
    }
    
    int main() { 
        multi::stream icl({"c:\\out1.txt", "c:\\out2.txt"});
        icl.attach(std::cout);
    
        icl << "Blah blah blah" << std::endl;
    }