我正在重载运算符<lt;如下所示:
std::ostream& operator<<(std::ostream& o, const MyClass& myobj);
现在,我想要两个版本的运算符<lt;,一个显示我的对象的简短描述,另一个显示更长的版本。
例如,MyClass可以包含有关客户端的信息。在短版本中,我只显示姓名,在长版本中,会显示更多细节,如生日、地址等。
在C++中有办法做到这一点吗?
我知道我可以有一个MyClass的方法来接收流,但它会被这样调用:
myObj.DisplayShort(cout)
或
myObj.DisplayLong(cout)
但我希望使用与通常形式类似的语法:
cout << myObj << endl;
标准方法是使用std::ios_base::xalloc
和std::ios_base::iword
创建自定义格式化标志和自定义操纵器。
所以你有
class MyClass {
static int fmt_flag_index;
enum fmt_flag { output_short, output_long };
}
您在程序启动时的某个位置初始化fmt_flag_index
:
int MyClass::fmt_flag_index = std::ios_base::xalloc();
这是您的自定义格式标志,可供使用。现在IO操纵器可以设置它:
std::ios_base& myclass_short(std::ios_base& os)
{
os.iword(MyClass::fmt_flag_index) = static_cast<int>(MyClass::output_short);
return os;
}
std::ios_base& myclass_long(std::ios_base& os)
{
os.iword(MyClass::fmt_flag_index) = static_cast<int>(MyClass::output_long);
return os;
}
并且operator<<
访问它:
std::ostream& operator<<(std::ostream& os, MyClass& f)
{
switch (static_cast<MyClass::fmt_flag>(os.iword(MyClass::fmt_flag_index)))
{
case MyClass::output_short: ...;
case MyClass::output_long: ...;
}
}
这样使用:
MyClass myobj;
std::cout << myclass_long << myobj;
std::cout << myclass_short << myobj;
演示
我会使用打印适配器:
class Adaptor
{
MyClass &adaptee;
operator <<
}
然后您可以基于以下内容实现不同的逻辑:
- 多个适配器类
- 具有数据成员的单个适配器类
- 带有模板参数的单个适配器类