2015-08-19 41 views
3

我想創建一個同時管理istream和ostream的類(IOObj)。我堅持的部分是如何正確覆蓋流操作符,以便給出使用isost的ostream和io >> x輸出的IOObj io {};,io << "blah" << std::endl輸出。我寫的流操作符不起作用。 std :: endl,可能大多數其他操作符都被忽略。C++:捆綁一個istream和一個ostream +覆蓋流操作符

以下是我的嘗試。

#ifndef IOOBJ_H_ 
#define IOOBJ_H_ 

#include <iostream> 
#include "SimpleTextUIErrors.h" 

namespace SimpleTextUI { 

class IOObj: public std::iostream { 
public: 

    IOObj(std::istream& in=std::cin, std::ostream& out=std::cout): 
     i{&in}, o{&out}, iOwner{false}, oOwner{false} {} 
    IOObj(std::istream& in, std::ostream* out): i{&in}, o{out}, iOwner{false}, oOwner{true} {} 
    IOObj(std::istream* in, std::ostream& out): i{in}, o{&out}, iOwner{true}, oOwner{false} {} 
    IOObj(std::istream* in, std::ostream* out): i{in}, o{out}, iOwner{true}, oOwner{true} {} 

    IOObj(const IOObj&)=delete; 
    IOObj& operator=(const IOObj&)=delete; 

    ~IOObj() { releaseIO(); } 

    std::istream& in() { return *i; } 
    std::ostream& out() { return *o; } 

    void setInput(std::istream* in); 
    void setInput(std::istream& in); 
    void setOutput(std::ostream* out); 
    void setOutput(std::ostream& out); 

    void outputSeparator() { *o << "-------------------------------" << std::endl; } 

protected: 
    IOObj(IOObj&&)=default; 
    IOObj& operator=(IOObj&&)=default; 

private: 
    std::istream* i; 
    std::ostream* o; 
    bool iOwner, oOwner; 

    void releaseIO() { 
     releaseIn(); 
     releaseOut(); 
    } 

    void releaseIn() { if (iOwner) delete i; } 
    void releaseOut() { if (oOwner) delete o; } 

}; 

template<typename T> 
inline IOObj& operator<<(IOObj& io, T output) { 
    io.out() << output; 
    if (io.out().fail()) throw OutputFailedError{}; 
    if (io.out().bad()) throw OutputBrokenError{}; 
    return io; 
} 

template<typename T> 
inline IOObj& operator>>(IOObj& io, T& input) { 
    io.in() >> input; 
    if (io.in().fail()) throw InputFailedError{}; 
    if (io.in().bad()) throw InputBrokenError{}; 
    return io; 
} 

} /* SimpleTextUI */ 

#endif /* IOOBJ_H_ */ 

回答

0

訣竅是在操縱器(如std :: endl)的情況下也寫一個函數。

我添加以下代碼:

inline IOObj& operator<<(IOObj& io, std::ostream& (*manip) (std::ostream&)) { 
    io.out() << manip; 
    if (io.out().fail()) throw OutputFailedError{}; 
    if (io.out().bad()) throw OutputBrokenError{}; 
    return io; 
} 

不幸的是,這個代碼是完全一樣的在我的代碼< <模板功能,只是專門實例化流處理器的功能。我無法解決這個問題(下面的評論,我會更新我的答案)。

此外,代碼可能需要另一個這樣的函數用於>>操作符,但邏輯幾乎相同。