天天看点

编写自己的流操作程序 经典代码

  自己写程序实现一个流操作符来完成流操作或者标准流不能完成的工作。或者自己自己写程序实现单个操作符来在一个流上设置多个标志而不是每次都调用多个操作符。

  下面请看一个简单的流操作程序:

#include <iostream>

#include <string>

  using namespace std;

  inline ios_base& floatnormal(ios_base& io) {

  io.setf(0, ios_base::floatfield);

  io.precision(4);

  io.width(10);

  return io;

}

  int main()

{

  ios_base::fmtflags flags = cout.flags();  //保存原有的流标志

  double pi = 3.14159265;

  cout << "pi=" << floatnormal << pi << std::endl;

  cout.flags(flags);    //恢复原有的流标志

  return 0;

  这里需要注意的是要保存原有的流标志,因为一旦使用流操作后,后续的流标志都会被修改,setw()除外。因此需要恢复原有的流标志,当然如果后续的流操作都使用相同的格式,不需要恢复。

  从这段代码代码可以看出,写字的流操作程序看起来是很简单的。但是如果要编写带有参数的的流操作呢?如:floatnormal(n),该如何编写呢?这就比较复杂了,而且要想写通用一些,更加需要较深的编程经验。

  笔者在这里有一个例子,供大家参考。这段代码比较经典,使用模板和函数指针也比较出色。

  template<typename T, typename C>

class ManipInfra

  private:

    T val_;

    basic_ostream<C>& (*manipFun_)(basic_ostream<C>&, T );

  public:

    ManipInfra(basic_ostream<C>& (*pFun)(basic_ostream<C>&, T), T val)

      : manipFun_ (pFun), val_(val){

    }

    void operator()(basic_ostream<C>& os) const {

      manipFun_(os, val_);

};

basic_ostream<C>& operator<<(basic_ostream<C>& os, const ManipInfra<T, C>& manip) {

  manip(os);

  return os;

  ostream& setTheWidth(ostream& os, int n) {

  os.width(n);

  ostream& setTheFill(ostream& os, char c) {

  os.fill(c);

  ManipInfra<int, char> setWidth(int n) {

  return ManipInfra<int, char>(setTheWidth, n);

  ManipInfra<char, char> setFill(char c) {

  return ManipInfra<char, char>(setTheFill, c);

  cout << setFill('*') << setWidth(19) << right << "djf\n";

     本文转自panpan3210 51CTO博客,原文链接:http://blog.51cto.com/panpan/116853,如需转载请自行联系原作者

继续阅读