我一直在谷歌上搜索周围,我无法找到一个简单的答案。它应该是简单的,作为STL通常为

我想定义MyOStream从标准:: ostream的公开继承。比方说,我想调用foo()每次的东西被写入到我流。

class MyOStream : public ostream {
public:
  ...
private:
   void foo() { ... }
}

据我所知,ostream的公共接口非虚,那么怎么能做到呢? 我希望客户能够同时使用运算符<<和write()和put()上MyOStream,并有使用我的课的扩展能力。

有帮助吗?

解决方案

这不是一个简单的问题,很遗憾。你应该从派生的类可以在basic_类,如basic_ostream。然而,从流推导可能不是你想要什么,你可能需要从流缓冲区,而不是导出,然后使用这个类实例化一个现有的流类。

在整个区域是复杂的,但有一个关于它的出色的书标准C ++输入输出流和语言环境,我建议你看看去任何进一步之前。

其他提示

我是纺纱我围绕着如何做同样的事情头,我发现,它实际上并不难。 基本上只是子类的ostream和流缓冲对象,并且与自己构建的ostream作为缓冲。虚拟溢()从性病::流缓冲将被要求发送到数据流中的每个字符。以适合你的例子我只是做了FOO()函数和调用它。

struct Bar : std::ostream, std::streambuf
{
    Bar() : std::ostream(this) {}

    int overflow(int c)
    {
        foo(c);
        return 0;
    }


    void foo(char c)
    {
        std::cout.put(c);

    }
};

void main()
{
    Bar b;
    b<<"Look a number: "<<std::hex<<29<<std::endl;
}

OH和忽视的事实是主要功能是不是一个真正的主函数。它在一个从其他地方称为命名空间; P

另一个工作劈以实现类似的效果是使用模板和组合物

class LoggedStream {
public:
  LoggedStream(ostream& _out):out(_out){}
  template<typename T>
  const LoggedStream& operator<<(const T& v) const {log();out << v;return *this;}
protected:
  virtual void log() = 0;
  ostream& out;
};

class Logger : LoggedStream {
  void log() { std::cerr << "Printing" << std::endl;}
};

int main(int,char**) {LoggedStream(std::cout) << "log" << "Three" << "times";}

我不知道这是否是正确的解决方案,但是从我的std :: ostream的继承了这种方式。它使用从标准:: basic_streambuf继承缓冲液和在时间(或更少,如果冲洗)获取64个字符,并将它们发送到一个通用的putChars()方法,其中,数据的实际处理就完成了。它还表明如何给用户数据。

实时实施例

#include <streambuf>
#include <ostream>
#include <iostream>

//#define DEBUG

class MyData
{
    //example data class, not used
};

class MyBuffer : public std::basic_streambuf<char, std::char_traits<char> >
{

public:

    inline MyBuffer(MyData data) :
    data(data)
    {
        setp(buf, buf + BUF_SIZE);
    }

protected:

    // This is called when buffer becomes full. If
    // buffer is not used, then this is called every
    // time when characters are put to stream.
    inline virtual int overflow(int c = Traits::eof())
    {
#ifdef DEBUG
        std::cout << "(over)";
#endif
        // Handle output
        putChars(pbase(), pptr());
        if (c != Traits::eof()) {
            char c2 = c;
            // Handle the one character that didn't fit to buffer
            putChars(&c2, &c2 + 1);
        }
        // This tells that buffer is empty again
        setp(buf, buf + BUF_SIZE);

        return c;
    }

    // This function is called when stream is flushed,
    // for example when std::endl is put to stream.
    inline virtual int sync(void)
    {
        // Handle output
        putChars(pbase(), pptr());
        // This tells that buffer is empty again
        setp(buf, buf + BUF_SIZE);
        return 0;
    }

private:

    // For EOF detection
    typedef std::char_traits<char> Traits;

    // Work in buffer mode. It is also possible to work without buffer.
    static const size_t BUF_SIZE = 64;
    char buf[BUF_SIZE];

    // This is the example userdata
    MyData data;

    // In this function, the characters are parsed.
    inline void putChars(const char* begin, const char* end){
#ifdef DEBUG
        std::cout << "(putChars(" << static_cast<const void*>(begin) <<
            "," << static_cast<const void*>(end) << "))";
#endif
        //just print to stdout for now
        for (const char* c = begin; c < end; c++){
            std::cout << *c;
        }
    }

};

class MyOStream : public std::basic_ostream< char, std::char_traits< char > >
{

public:

    inline MyOStream(MyData data) :
    std::basic_ostream< char, std::char_traits< char > >(&buf),
    buf(data)
    {
    }

private:

    MyBuffer buf;

};

int main(void)
{
    MyData data;
    MyOStream o(data);

    for (int i = 0; i < 8; i++)
        o << "hello world! ";

    o << std::endl;

    return 0;
}

的组合物,不继承。你的类包含, “换行” 一个ostream&,并转发到它(调用foo()之后)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top