继承自std :: basic_streambuf以写入套接字

时间:2017-01-20 23:14:18

标签: c++ inheritance stream iostream streambuf

我想编写一个自己的日志库,为日志条目的发送位置提供抽象。

C ++的IO库已经通过public function delete($id) { $data = self::find($id)->delete(); return $data; } std::stringstream提供了这种抽象。我也希望能够从套接字读取/写入。

我读到扩展标准库的正确方法是继承std::fstream。我不明白的是,如果继承std::basic_streambuf之类的std::basic_streambuf,那么std::basic_filebufstd::ifsreamstd::ofstream类的需求在哪里? ?我不能用std::fstream子类的实例替换某些流的缓冲区,它输出我想要的地方吗?

到目前为止,我已经完成了以下工作,但我真的不确定自己在做什么。以下设计是否正确?

std::basic_streambuf

编辑:根据答案更新代码:

template< typename char_type, typename traits_type = std::char_traits< char_type > >
class basic_sock_streambuf : public std::basic_streambuf< char_type, traits_type >
{
public:

    basic_sock_streambuf()
    {

    }

    ~basic_sock_streambuf()
    {

    }

    int overflow (int c = EOF)
    {
        fputc( c, stdout ); // Temporary.
        return traits_type::to_int_type( c );
    }

    int underflow()
    {
        return fgetc( stdout ); // Temporary.
    }

    int sync()
    {
        return 0;
    }
};

template< typename char_type, typename traits_type = std::char_traits< char_type > >
class basic_isockstream : public std::basic_istream< char_type, traits_type >
{
};

template< typename char_type, typename traits_type = std::char_traits< char_type > >
class basic_osockstream : public std::basic_ostream< char_type, traits_type >
{
};

template< typename char_type, typename traits_type = std::char_traits< char_type > >
class basic_socktream : public basic_isockstream< char_type, traits_type >, public basic_osockstream< char_type, traits_type >
{
private:

    typedef basic_isockstream< char_type, traits_type > iparent;

    typedef basic_osockstream< char_type, traits_type > oparent;

    basic_sock_streambuf< char_type, traits_type > sock_sb;

    std::basic_streambuf< char_type, traits_type > * old_isb;

    std::basic_streambuf< char_type, traits_type > * old_osb;

public:

    basic_socktream()
    {
        old_isb = iparent::rdbuf( & sock_sb );
        old_osb = oparent::rdbuf( & sock_sb );
    }

    ~basic_socktream() throw()
    {
        iparent::rdbuf( old_isb );
        oparent::rdbuf( old_osb );
    }
};

1 个答案:

答案 0 :(得分:4)

std::istreamstd::ostream提供格式化的输入和输出操作。也就是说,将流转换为数字,字符串等...

std::basic_streambuf是一个较低级别的接口,可以在某处读取或写入字符块。这就是你需要子类化和实现的。

而且,你走在正确的轨道上。 std::istreamstd::ostream都有一个重载的构造函数,它接受一个指向流缓冲区的指针。所以,你的行动计划是:

  1. 子类并实施自定义std::basic_streambuf

  2. 使用指向流缓冲区的指针构建std::istreamstd::ostream

  3.   

    我不能只用一个实例替换某些流的缓冲区   std :: basic_streambuf

    的子类

    不,不是替换,而是构建一个。您使用指向缓冲区的指针构造std::istreamstd::ostream。您不会使用std::[io]fstream,而是使用您的流缓冲区构建的std::istreamstd::ostream

    例如,std::ifstream的所有内容都是std::istream的子类,它使用指向从文件读取的内部流缓冲区的指针构造其超类。

    随意创建自己的std::istream子类,它从流缓冲区子类中继承,并std::istream首先构造流缓冲区子类,然后构造std::istream。< / p>