我想将类实例的文本描述放到 ostream 上,如
ostream << myInstance;
我知道如何声明一个 ostream 插入器;
ostream& operator<<(ostream&, myClass&);
我希望能够将不同级别的细节放到 ostream 中。如果我可以定义两个或多个 ostream 插入器,或者向插入器传递一个额外的参数,或者向插入器传递一个方法,或者调用一个返回字符串流的方法,我就可以做到这一点(我可以这样做吗?)
有没有人解决过这个问题?
我想将类实例的文本描述放到 ostream 上,如
ostream << myInstance;
我知道如何声明一个 ostream 插入器;
ostream& operator<<(ostream&, myClass&);
我希望能够将不同级别的细节放到 ostream 中。如果我可以定义两个或多个 ostream 插入器,或者向插入器传递一个额外的参数,或者向插入器传递一个方法,或者调用一个返回字符串流的方法,我就可以做到这一点(我可以这样做吗?)
有没有人解决过这个问题?
您可以通过实际封装流本身来将“标志”添加到流中。
struct Verbose {
explicit Verbose(std::ostream* s = 0): _stream(s) {}
std::ostream* _stream;
};
Verbose operator<<(std::ostream& out, Verbose) {
return Verbose(&out);
}
然后,为详细输出定义一个新的运算符:
std::ostream& operator<<(Verbose v, MyClass const& mc) {
assert(v._stream);
std::ostream& out = *v._stream;
// ...
return out;
}
用法:
std::cout << Verbose() << myInstance << "\n";
你会注意到它Verbose根本不依赖于类,并且可以很容易地在类中重用。
注意:如果你愿意,你可以添加一个额外的参数来Verbose直接控制详细程度。
标准的解决方案是定义一个自定义操纵器,使用存储在由ios::xalloc. 就像是:
int
flagIndex()
{
static int const theIndex = std::ostream::xalloc();
return theIndex;
}
std::ostream&
verbose( std::ostream& stream )
{
stream.iword( flagIndex() ) = 1;
return stream;
}
std::ostream&
unverbose( std::ostream& stream )
{
stream.iword( flagIndex() ) = 0;
return stream;
}
std::ostream&
operator<<( std::ostream& dest, MyClass const& object )
{
bool verbose = dest.iword( flagIndex() ) != 0;
// ...
return dest;
}
然后,您可以编写如下内容:
std::cerr << verbose << myObject;
您不能向 中添加额外的参数operator<<,但您可以轻松定义采用详细参数的自定义打印函数:
void dump(ostream& ostr, const myClass& obj, int verbosity = 1)
{
if (verbosity > 2)
ostr << "Very verbose!\n";
if (verbosity > 1)
ostr << "Verbose!\n";
if (verbosity > 0)
ostr << "Standard!\n";
ostr << "Minimal.\n";
}
用法:
dump(cout, myobj); // Default
dump(cout, myobj, 0); // Minimal
dump(cout, myobj, 1); // Default
dump(cout, myobj, 2); // Verbose
dump(cout, myobj, 3); // Very verbose
您还应该提供一个流操作符转发到dump(),使用默认的详细程度:
ostream& operator<<(ostream& ostr, const myClass& obj)
{
dump(ostr, obj);
return ostr;
}
如果您想遵循这种方式,最好enum为详细程度声明 an 而不是使用ints:
enum Verbosity
{
MinimalOutput = 0,
StandardOutput = 1,
VerboseOutput = 2,
DebugOutput = 3
};
修改项目格式的标准方法是实现操纵器。它通常只会设置一些标志。然后,您的插入器将根据标志的状态修改其行为。