iomanip.h 中包含的其中一个参数化操纵符是 setfill。setfill 设置用于填写字段宽度的字符。该操纵符是按下例所示的方式实现的:
//file setfill.cc #include<iostream.h> #include<iomanip.h> //the private manipulator static ios& sfill(ios& i, int f) { i.fill(f); return i; } //the public applicator smanip_int setfill(int f) { return smanip_int(sfill, f); }
参数化操纵符的实现分为两部分:
操纵符。它使用一个额外的参数。在上面的代码示例中,采用了额外的 int 参数。由于未对这个操纵符函数定义移位运算符,所以您无法将它放至输入或输出操作序列中。相反,您必须使用辅助函数 applicator。
applicator。它调用该操纵符。applicator 是全局函数,您会为它生成在头文件中可用的原型。通常操纵符是文件中的静态函数,该文件包含了 applicator 的源代码。该操纵符仅由 applicator 调用。如果将其指定为静态的,您需要确保它的名称不在全局地址空间中。
头文件 iomanip.h 中定义了多个类。每个类都保存一个操纵符函数的地址和一个参数的值。manip(3CC4) 手册页中介绍了 iomanip 类。上一示例使用了 smanip_int 类,该类可与 ios 一起使用。因为该类与 ios 一起使用,所以也可以与 istream 和 ostream 一起使用。上面的示例还使用了另一个类型为 int 的参数。
applicator 创建并返回类对象。在上面的代码示例中,类对象是 smanip_int,其中包含了操纵符和 applicator 的 int 参数。iomanip.h 头文件定义了用于该类的移位运算符。如果 applicator 函数 setfill 在输入或输出操作序列中,会调用该 applicator 函数,且其返回一个类。移位运算符作用于该类,以使用其参数值(存储在类中)调用操纵符函数。
在以下示例中,操纵符 print_hex 执行以下操作:
此处使用了类 omanip_long,因为该代码示例仅用于输出。它对 long 而不是对 int 进行操作:
#include <iostream.h> #include <iomanip.h> static ostream& xfield(ostream& os, long v) { long save = os.setf(ios::hex, ios::basefield); os << v; os.setf(save, ios::basefield); return os; } omanip_long print_hex(long v) { return omanip_long(xfield, v); }