我想编写一个自己的日志库,为日志条目的发送位置提供抽象。
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_filebuf
,std::ifsream
和std::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 );
}
};
答案 0 :(得分:4)
std::istream
和std::ostream
提供格式化的输入和输出操作。也就是说,将流转换为数字,字符串等...
std::basic_streambuf
是一个较低级别的接口,可以在某处读取或写入字符块。这就是你需要子类化和实现的。
而且,你走在正确的轨道上。 std::istream
和std::ostream
都有一个重载的构造函数,它接受一个指向流缓冲区的指针。所以,你的行动计划是:
子类并实施自定义std::basic_streambuf
。
使用指向流缓冲区的指针构建std::istream
或std::ostream
。
我不能只用一个实例替换某些流的缓冲区 std :: basic_streambuf
的子类
不,不是替换,而是构建一个。您使用指向缓冲区的指针构造std::istream
或std::ostream
。您不会使用std::[io]fstream
,而是使用您的流缓冲区构建的std::istream
和std::ostream
。
例如,std::ifstream
的所有内容都是std::istream
的子类,它使用指向从文件读取的内部流缓冲区的指针构造其超类。
随意创建自己的std::istream
子类,它从流缓冲区子类中继承,并std::istream
首先构造流缓冲区子类,然后构造std::istream
。< / p>