我需要实现一个c++ iostream操纵符。阅读这里和那里,人们似乎使用两种方式
-
使用
ios_base::xalloc
和ios_base::iword
-
实现iostream的派生类,类似下面的例子。
我喜欢第二种方式,但与第一种方式相比,它可能有我无法看到或理解的缺点。
// Example of point 2
struct mystream : public iostream
{
ostream& o_;
mystream(ostream& o) : o_(o) {}
ostream& operator << (int a) {
// do something with o and a
o << "<A>" << a << "</A>";
return *this;
}
};
ostream mymanipulator(ostream& out) {
return mystream(out);
}
我在这篇文章中找到了一种非常好的方法#2的实现。
在我看来,xalloc and iword
更多的是用来存储一些自定义的内部状态,为我的自定义流在某些时候使用。
我不推荐这两种方法。
使用
ios_base::xalloc
和ios_base::iword
你还没有确切地告诉我们你将如何使用存储在流中的数据,但是每次你想写的时候都设置iword()
有点不直观。
实现
iostream
的派生类…
通常你不希望继承流基类。它可能有用的唯一情况是当您在流缓冲区周围包装自定义流时,但这通常是为了方便。
另一个问题是您的插入器返回std::ostream
,这意味着当链接操作符时,您只会在第二次写入时写入std::ostream
基对象:
mystream str;
str << 100 // writes "<A>100</A>"
<< 200; // only writes 200
惯用的解决方案是为流的区域设置定制一个
std::num_put<char>
facet。通过这种方式,您可以将功能直接封装在流的底层,这样就不会改变用户使用流的方式。