【发布时间】:2017-06-06 01:06:41
【问题描述】:
我想写一个我自己的日志库,为日志条目发送到哪里提供抽象。
C++ 的 IO 库已经通过 std::stringstream 和 std::fstream 提供了这种抽象。我还希望能够从/向套接字读取/写入。
我读到扩展标准库的正确方法是从std::basic_streambuf 继承。我不明白的是,如果像std::basic_filebuf 那样从std::basic_streambuf 继承,那么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 );
}
};
【问题讨论】:
-
好消息,这实际上很容易做到。
-
不错。一次写一些缓冲区怎么样?
-
读/写缓冲区 goto streambuf::xsget() , -xsput() 这是套接字流的典型访问
标签: c++ inheritance stream iostream streambuf