将对象插入流中

时间:2011-11-23 17:08:39

标签: c++ c++-standard-library

我想将类实例的文本描述放在ostream中,如

ostream << myInstance;

我知道如何声明一个ostream插件;

ostream& operator<<(ostream&, myClass&);

我希望能够为ostream添加不同级别的细节。如果我可以定义两个或更多的ostream插入器,或者将一个额外的参数传递给插入器,或者将一个方法传递给插入器,或者调用一个返回字符串流的方法(我可以这样做吗?)

有没有人解决过这个问题?

4 个答案:

答案 0 :(得分:2)

您可以通过实际包含流本身来将“标记”添加到流中。

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添加一个额外的参数,以直接在那里实际控制详细程度。

答案 1 :(得分:2)

标准解决方案是使用标志或定义自定义操纵器 存储在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;

答案 2 :(得分:1)

您无法向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而不是使用int s:

enum Verbosity
{
    MinimalOutput = 0,
    StandardOutput = 1,
    VerboseOutput = 2,
    DebugOutput = 3
};

答案 3 :(得分:0)

修改项目格式的标准方法是实现操纵器。它通常只会设置一些标志。然后,您的插入器将根据标志的状态修改其行为。