提问人:Virus721 提问时间:1/21/2017 最后编辑:Virus721 更新时间:1/22/2017 访问量:3855
继承自 std::basic_streambuf 以写入套接字
Inheriting from std::basic_streambuf to write to a socket
问:
我想编写一个我自己的日志库,为日志条目发送到的任何地方提供抽象。
C++ 的 IO 库已经提供了这种抽象,带有 和 。我还希望能够从套接字读/写。std::stringstream
std::fstream
我读到扩展标准库的正确方法是继承 .我不明白的是,如果从 like 继承,哪里需要 和 类?我不能将某个流的缓冲区替换为子类的实例,该子类的子类输出到我想要的位置吗?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 );
}
};
编辑:根据答案更新代码:
template<
typename char_type,
typename traits_type = std::char_traits< char_type > >
class basic_sockbuf :
public std::basic_streambuf< char_type, traits_type >
{
public:
basic_sockbuf()
{
}
~basic_sockbuf()
{
}
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 >
{
private:
typedef std::basic_istream< char_type, traits_type > parent;
basic_sockbuf< char_type, traits_type > buffer;
public:
basic_isockstream() :
std::basic_istream< char_type, traits_type >::basic_istream(),
buffer()
{
init( & buffer );
}
};
template<
typename char_type,
typename traits_type = std::char_traits< char_type > >
class basic_osockstream :
public std::basic_ostream< char_type, traits_type >
{
private:
basic_sockbuf< char_type, traits_type > buffer;
public:
basic_osockstream() :
std::basic_ostream< char_type, traits_type >::basic_istream(),
buffer()
{
init( & buffer );
}
};
template<
typename char_type,
typename traits_type = std::char_traits< char_type > >
class basic_socktream :
public std::basic_iostream< char_type, traits_type >,
public basic_sockbuf< char_type, traits_type >
{
private:
basic_sockbuf< char_type, traits_type > buffer;
public:
basic_socktream() :
std::basic_iostream< char_type, traits_type >::basic_iostream(),
buffer()
{
std::basic_iostream< char_type, traits_type >::init( & buffer );
}
};
答:
std::istream
并提供格式化的输入和输出操作。也就是说,将流转换为数字、字符串等/从数字、字符串等转换......std::ostream
std::basic_streambuf
是一个较低级别的接口,用于读取或写入字符块或从中读取或写入字符块......地方。这就是您需要子类化和实现的内容。
而且,您走在正确的轨道上。两者都有一个重载构造函数,该构造函数采用指向流缓冲区的指针。因此,您的行动计划是:std::istream
std::ostream
子类化并实现您的自定义 .
std::basic_streambuf
使用指向流缓冲区的指针构造 a 或 a。
std::istream
std::ostream
我不能用 std::basic_streambuf 的子类
不,不是替换,而是构建一个。使用指向缓冲区的指针构造 a 或 a。您不会使用 ,而是使用流缓冲区构造的 和 。std::istream
std::ostream
std::[io]fstream
std::istream
std::ostream
例如,所有 a 都是一个子类,该子类构造其超类,其中包含指向从文件中读取的内部流缓冲区的指针。std::ifstream
std::istream
您可以随意创建自己的子类 ,该子类从流缓冲区子类乘以继承,并且 首先构造流缓冲区子类,然后构造 .std::istream
std::istream
std::istream
评论
streambuf
basic_sockstream
basic_sockstream
streambuf
basic_istream
basic_ostream
basic_isockstream
basic_osockstream
std::ostream
class basic_osockstream : public basic_sock_streambuf< ... >, public std::basic_ostream< char_type, traits_type >
basic_osockstream(): parent(this)
fstream
ifstream
ofstream
basic_sockstream
basic_osockstream
basic_isockstream
basic_sock_streambuf
basic_istream
评论