gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 16:17:09 25 4
gpt4 key购买 nike

我想编写一个我自己的日志记录库,为日志条目发送到的任何地方提供抽象。

C++ 的 IO 库已经通过 std::stringstreamstd::fstream 提供了这种抽象。我还希望能够从套接字读取/向套接字写入。

我读到扩展标准库的正确方法是继承std::basic_streambuf。我不明白的是,如果像 std::basic_filebuf 那样从 std::basic_streambuf 继承,那么哪里需要 std::ifsreamstd::ofstreamstd::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::istreamstd::ostream 提供格式化的输入和输出操作。也就是说,将流与数字、字符串等相互转换...

std::basic_streambuf 是一个较低级别的接口(interface),用于从...某处读取或写入字符 block 。这就是您需要子类化和实现的内容。

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

  1. 子类化并实现您的自定义 std::basic_streambuf

  2. 使用指向流缓冲区的指针构造一个 std::istream 或一个 std::ostream

Can't I just replace the buffer of some stream with a instance of a subclass of std::basic_streambuf

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

例如,std::ifstreamstd::istream 的子类,它使用指向内部流缓冲区的指针构造其父类(super class)从文件中读取。

随意创建您自己的 std::istream 的子类,它从您的流缓冲区子类继承而来,而 std::istream 构造流缓冲区首先是子类,然后是 std::istream

关于c++ - 继承自 std::basic_streambuf 以写入套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41773881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com