C ++:将istream和ostream + override流操作符捆绑在一起

时间:2015-08-19 06:56:26

标签: c++ stream iostream

我想创建一个管理istream和ostream的类(IOObj)。我坚持的部分是如何正确覆盖流操作符,以便使用ostream给出IOObj io {};io << "blah" << std::endl输出,并使用istream给x输入io >> x。我写的流操作符无法工作。只需忽略std :: endl,可能还有其他大多数操纵器。

以下是我的尝试。

#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_ */

1 个答案:

答案 0 :(得分: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;
}

不幸的是,这段代码与&lt;&lt;完全相同我的代码中的模板函数,只是为流操纵器函数特别实例​​化。我无法解决这个问题(下面的评论,我会更新我的答案)。

此外,代码可能需要另一个此类函数用于&gt;&gt;运算符,但逻辑几乎相同。