为一个类打印(打印调试信息)的最佳做法是什么?

what's the best practice to print out(print debugging information) for a class?

我想知道打印出 class(比如 classA)的最佳做法是什么,我有几种方法

class约;

1) 定义一个调试方法,在这个方法中,打印出它的所有成员。

2) 定义一个str()方法,并使用cout<< ca.str()

3) 定义类似字符串转换的东西(我还不确定如何),然后只使用 cout << ca

通常的方法是重载operator<<,大致像这样:

std::ostream &operator<<(std::ostream &out, classA const &a) {
  // precise formatting depends on your use case. Do the same thing you would
  // if you wanted to print a to cout or a file, because that is what this code
  // will end up doing.
  out << a.some_data() << ", " << a.some_more_data();
  return out;
}

如果classA接口有限(不公开所有相关数据成员),可能需要将operator<<设为classAfriend,比如

class A {
public:
  // stuff

  friend operator<<(std::ostream &out, classA const &a);
};

// private members can then be accessed
std::ostream &operator<<(std::ostream &out, classA const &a) {
  out << a.some_private_member << ", " << a.some_other_private_member;
  return out;
}

通常没有充分的理由来阻止对私有成员的读取访问,然后您允许用户根据 operator<< 转储出来,因为这将是相当漏洞的访问控制。

这样你就可以编写

classA a;
std::cout << a;

std::ofstream file("foo.txt");
file << a;

std::ostringstream fmt;
fmt << a;
std::string s = fmt.str();

等等。

作为样式注释:可以这样写

std::ostream &operator<<(std::ostream &out, classA const &a) {
  // precise formatting depends on your use case
  return out << a.some_data() << ", " << a.some_more_data();
}

这实现了与拆分 return 相同的效果,因为 operator<<(按照惯例)return 是传递给它的相同流对象(以启用[的链接=22=] 如 std::cout << i << j << k;).

样式注释 2:如果 classA 中没有任何内容使它变得困难,则此技术的升级是写

template<typename char_type>
std::basic_ostream<char_type> &operator<<(std::basic_ostream<char_type> &out, classA const &a) {
  // rest as before. Put it in a header because it is a function template now.
}

这使您不仅可以将 classA 对象写入 coutcerrclogofstreamostringstream 等。 ,还有他们的 wchar_t 同行 wcoutwcerrwclogwofstreamwostringstream。这些在实践中很少使用,但通常实现此功能不会花费您任何成本。诀窍在于 std::ostreamstd::wostream——所有这些输出流的基础 类——分别是 std::basic_ostream<char>std::basic_ostream<wchar_t> 的别名。这为我们提供了一种很好的方式来处理两个(以及可能的其他)字符 类 而无需代码重复。

如果您想在某个文件中记录您的流程步骤并稍后查看该文件以查看出现了什么问题,则可以选择阻塞。您还可以通过在外部文件中记录数据成员来定期检查数据成员的状态。