C++常见问题解答中类层次结构的打印模式
Printing Pattern for a Class Hierarchy in the C++ FAQ
我正在为类层次结构实现打印模式,如C++常见问题解答中所述。在FAQ中,打印函数在基类中声明如下:
protected:
virtual void printOn(std::ostream& o) const = 0; // pure virtual
// -- or --
virtual void printOn(std::ostream& o) const; // plain virtual
我正在考虑实现printOn
方法的纯虚拟版本,但有一个变体。我想将返回类型从void
更改为std::ostream&
,如下所示:
protected:
virtual std::ostream& printOn(std::ostream& o) const;
在我看来,这种方法的优点是使用链接方法可以更容易地将基类的输出合并到派生类的输出中。这里有一个例子:
std::ostream& DerivedClass::printOn(std::ostream& stream) const
{
return stream
<< "<DerivedClass>" << 'n'
<< BaseClass::printOn(stream)
<< "<member_one>" << member_one_ << "</member_one>" << 'n'
<< "<member_two>" << member_two_ << "</member_two>" << 'n'
<< "</DerivedClass>" << std::endl;
}
相反,如果虚拟BaseClass::printOn
方法声明为void
,则DerivedClass::printOn
的外观如下FAQ:所示
void DerivedClass::printOn(std::ostream& stream) const
{
stream << "<DerivedClass>" << 'n';
BaseClass::printOn(stream);
stream
<< "<member_one>" << member_one_ << "</member_one>" << 'n'
<< "<member_two>" << member_two_ << "</member_two>" << 'n'
<< "</DerivedClass>" << std::endl;
}
问题:有人认为我对printOn
返回类型的修订有任何缺陷吗?
如果BaseClass::printOn(stream)
返回std::ostream &
,则无法写入
stream << ... << BaseClass::printOn(stream) << ...;
你必须写:
stream << ...;
BaseClass::printOn(stream) << ...;
显然,这几乎不比它返回void
的情况好。您可以返回一个带有no-op-stream-out运算符的类型:
struct noop_manipulator {
noop_manipulator(std::ostream &) {}
friend inline std::ostream &operator<<(std::ostream &os, const noop_manipulator &) {
return os;
}
};
noop_manipulator DerivedClass::printOn(std::ostream& stream) const
{
return stream << ...;
}
或者,您可以随意使用语法:
void DerivedClass::printOn(std::ostream& stream) const
{
return stream << "<DerivedClass>" << 'n',
BaseClass::printOn(stream), stream
<< "<member_one>" << member_one_ << "</member_one>" << 'n'
<< "<member_two>" << member_two_ << "</member_two>" << 'n'
<< "</DerivedClass>" << std::endl;
}
所有这些方法的缺点是,它们掩盖了超类虚拟调用的使用,这非常不寻常,因此应该尽可能清楚。所描述的印刷图案本身就很不寻常;除非已经有了虚拟继承层次结构,否则派生类通常会有自己的operator<<
,并通过static_cast
对基类引用调用基类operator<<
。
相关文章:
- 如何循环打印顶点结构
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 如何在c++中打印目录
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 使用递归 c++ 打印模式
- 只需要知道我在c ++中打印模式的方式是否有效,或者有另一种方法可以有效地做到这一点
- 逻辑:如何在C / C++中打印Pseudo_random位序列模式
- 打印号码模式
- 找不到模式时如何打印"no mode"?
- 以正确的模式打印数据
- 打印重复数字模式
- 在编译时分配内存的工厂模式,以及如何打印编译时信息
- 如何处理混合模式项目中的打印
- 在释放模式下,cout 不打印任何内容
- 如果命令不只是打印结果,而是进入某种交互模式,如何处理来自C++的终端命令执行的输出?
- 如何在C++中打印此模式而不使用“std::setw”、“std:;left”和“std::right”
- 以二进制模式打印到STL(立体光刻)文件
- 当Unicode模式打开时,打印到VS2010中的调试输出
- C++常见问题解答中类层次结构的打印模式