c++ - 在用于输出的操作符<<函数中设置浮点字段,然后将其更改回来

标签 c++ operator-overloading ostream

假设我有一些商品类,其中有一个名为价格的字段。当有人尝试输出我的 Merchandise 对象时(最常见的是使用 cout),我想显示该商品售价的美元金额,精确到小数点后两位。但我不想做的是永久改变流。例如,如果有人这样做:

double someNumber;  //someNumber should be displayed to 3 decimal places
Merchandise product;
/* something happens to product here */

cout << product << "And the number generated is " << someNumber << endl;

在这种情况下,product 应显示两位小数,但 someNumber 仍应显示 3 位,就像客户期望的那样。所以我不想在实现我的函数时永久更改ostream,我只想为这一字段显示2个小数位,然后将其恢复正常。我该怎么做?

我尝试更改一次 ostream 标志,然后将它们改回来,如下所示:

ostream& operator<< (ostream& os, const Merchandise& rhs) {
  int precision = os.precision();  //Get the current precision so we can change it back later
  /* I don't know how to get the current floatfield */
  os.setf(std::ios::fixed, std::ios::floatfield);  //Forces the same precision all the time
  os.precision(2);  //Forces a precision of 2

  os << rhs.price;

  os.precision(precision);
  /* I can't change the floatfield back, since I don't know how to get it or what kind of object to store it in */ 

  return os;
}

我只是一边做一边想办法。我不知道这是否是最好的或标准的方法。如果有更好的方法,有人可以告诉我吗?如果没有,那么如何将当前的 floatfield 存储在变量中,以及使用什么类型的对象来存储它?谢谢。

最佳答案

precision() 在设置新精度时也会返回旧精度,因此您可以利用它并与赋值内联设置精度:

std::streamsize precision = os.precision(2);

std::streamsize 与窄字符流(使用 char 的流)的 int 相同,但为了获得最佳实践,您应该那种类型。

此外,要保存标志,您应该将流的标志存储在 std::ios_base::fmtflags 类型的对象中:

std::ios_base::fmtflags flags = os.flags(os.flags() | std::ios_base::fixed);

完成后只需将其更改回来即可。


您可以通过使用 RAII 技术在完成后将设置更改回来来促进此操作:

template <typename Stream>
class format_saver
{
public:
    format_saver(Stream& os)
        : os_(os)
        , flags(os.flags())
        , precision(os.precision())
    { }

    ~format_saver() { os_.flags(flags); os_.precision(precision); }
private:
    Stream& os_;
    std::ios_base::fmtflags flags;
    std::streamsize         precision;
};

现在你可以做:

std::ostream& operator<<(std::ostream& os, const Merchandise& rhs)
{
    format_saver<std::ostream> _(os);
    return os << std::setprecision(2) << std::fixed << rhs.price;
}

关于c++ - 在用于输出的操作符<<函数中设置浮点字段,然后将其更改回来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23923990/

相关文章:

c++ - 与 'operator<<' 不匹配(操作数类型为 'std::ostream {aka std::basic_ostream<char>}'

c++ - 子对象上的 ostream 获取其父对象的 ostream

c++ - 如何跟踪外部代码修改类变量的所有位置?

c++ - Qt C++ - 如何获取 QPlainTextEdit 的当前行和列

C++:如何将unicode字符打印到文本文件

c++ - C++中指针结构的运算符重载

c++ - Microsoft 重载 << 运算符示例会引发链接错误

c++ - 同步 : Detecting Pointer/Clicks

c# - 字符串转换不起作用

C++ 重载 << 错误