- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想做一些类似下面代码所示的事情:
class foo
{
private:
std::fstream* m_stream;
public:
foo(std::fstream* stream) : m_stream(stream) { }
foo& write(char const* s, std::streamsize count)
{
if (/*condition*/)
{
m_stream->write(s, count);
}
else
{
// ...
}
return *this;
}
foo& read(char* s, std::streamsize count)
{
if (/*condition*/)
{
m_stream->read(s, count);
}
else
{
// ...
}
return *this;
}
};
我需要为所有类似的方法添加相同的行为(例如 put
)。这不应仅应用于文件流,而是应用于所有其他流类。有什么简单的方法可以实现这些功能吗?
最佳答案
许多格式化输出运算符 ( operator<<
) 直接写入底层流缓冲区。为了以一般方式完成此操作,您需要做的是从 std::basic_streambuf 派生一个类,将所有数据转发到另一个 std::basic_streambuf,然后可选地创建一个最小的 std::basic_ostream 实现以使用您的流缓冲更容易。
不过,我不会说这特别容易,但这是可以影响所有流类型的唯一方法。
这是一个转发到另一个流缓冲区的最小流缓冲区的示例(并执行一些无意义的转换只是为了演示您可以做什么),以及一个伴随的流:
#include <iostream>
#include <streambuf>
template<typename CharType, typename Traits = std::char_traits<CharType> >
class ForwardingStreamBuf : public std::basic_streambuf<CharType, Traits>
{
public:
typedef Traits traits_type;
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
ForwardingStreamBuf(std::basic_streambuf<CharType, Traits> *baseStreamBuf)
: _baseStreamBuf(baseStreamBuf)
{
}
protected:
virtual int_type overflow(int_type c = traits_type::eof())
{
if( _baseStreamBuf == NULL )
return traits_type::eof();
if( traits_type::eq_int_type(c, traits_type::eof()) )
return traits_type::not_eof(c);
else
{
CharType ch = traits_type::to_char_type(c);
if( ch >= 'A' && ch <= 'z' )
ch++; // Do some meaningless transformation
return _baseStreamBuf->sputc(ch);
}
}
virtual int sync()
{
if( _baseStreamBuf == NULL )
return -1;
else
return _baseStreamBuf->pubsync();
}
private:
std::basic_streambuf<CharType, Traits> *_baseStreamBuf;
};
template<typename CharType, typename Traits = std::char_traits<CharType> >
class ForwardingStream : public std::basic_ostream<CharType, Traits>
{
public:
ForwardingStream(std::basic_ostream<CharType, Traits> &stream)
: std::basic_ostream<CharType, Traits>(NULL), _buffer(stream.rdbuf())
{
this->init(&_buffer);
}
ForwardingStreamBuf<CharType, Traits>* rdbuf() const
{
return &_buffer;
}
private:
ForwardingStreamBuf<CharType, Traits> _buffer;
};
这可以非常简单地使用:
int main()
{
ForwardingStream<char> test(std::cout);
test << "Foo" << std::endl;
}
这会输出 Gpp
.希望对您有所帮助。
关于C++ 装饰 basic_iostream 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6384860/
我想做一些类似下面代码所示的事情: class foo { private: std::fstream* m_stream; public: foo(std::fstream* str
我有一个指向 const *char 缓冲区的指针及其长度,我正在尝试使用接受以下类型对象的 API(在本例中为 AWS S3 C++ upload request): std::basic_iost
就在我认为我了解 C++11 中 iostream 的多遍移动构造时(感谢 https://stackoverflow.com/a/8156356/273767 的介绍),我遇到了这个: §27.7.
我是一名 C++ 开发人员,主要在 Solaris 和 Linux 上编程,直到最近,当我被迫创建一个针对 Windows 的应用程序时。 我一直在使用基于 TCP 套接字支持的 C++ I/O 流的
我安装了ligstdc++-4.9-dev和libstdc++-4.9-doc,想通过man<扫描c++的库信息 就像 C 中的样式。但是当我运行“man std::iostream”时,我遇到一个错
我是一名优秀的程序员,十分优秀!