将 Class 对象转换为字符串

Convert Class Object to String

我有一个 class 的作业,要求我使用两个必需的、教师定义的空函数将 class 对象 clock_time 转换为字符串:to_string() 和重载的 << 运算符。我无法让它工作,我不确定为什么。

clock_time::clock_time(int h, int m, int s)
{
    set_time(h, m, s);
}

void clock_time::set_time(int h, int m, int s)
{
    _seconds = h * 3600 + m * 60 + s;
}

string to_string(clock_time c)
{
    ostringstream ss;
    ss << c;
    return ss.str();
}

ostream& operator<<(ostream &out, clock_time c)
{
    out << to_string(c);
    return out;
}

问题的症结在于 to_string 方法对 clock_time 使用了 operator<< 重载。不幸的是,operator<< 重载使用了 to_string 方法。显然这是行不通的,因为它会永远绕圈子。

那么我们如何修复它才能正常工作呢?

我们将 to_stringoperator<< 解耦,这样它们就不会互相调用。

首先,让我们定义一个伪造的例子clock_time,因为它不见了,没有它我们就做不到。

class clock_time
{
    int hour;
    int minute;
    int second;

public:
    friend std::ostream& operator<<(std::ostream &out, clock_time c);
}

注意 operator<< 作为 clock_timefriend 函数的声明。这允许 operator<< 打破封装并使用 clock_time 的私有成员。这可能不是必需的,具体取决于 clock_time 的定义方式,但对于此示例,它几乎是整个 shebang 的关键。

接下来我们实现operator<<

ostream& operator<<(ostream &out, clock_time c)
{
    out << c.hour << ":" << c.minute << ":" << c.second;
    return out;
}

我选择了这种输出格式,因为这是我希望在数字时钟上看到的格式。最少惊喜法则说,给人们他们所期望的,你就会有更少的错误和不好的感觉。混淆人们并... 还记得微软从 Windows 8 中拉出开始菜单时发生了什么吗?或者当可口可乐改变他们的配方时?

我先做 operator<< 是因为个人喜好。我宁愿在这里做繁重的工作,因为出于某种原因,这比在 to_string 中做对我来说更容易。

现在我们已准备好实施 to_string 功能。

string to_string(clock_time c)
{
    ostringstream ss;
    ss << c;
    return ss.str();
}

惊喜!它与 OP 最初实现的完全相同。因为 to_stringoperator<< 已经解耦,所以 operator<< 可以在 to_string 中使用。你可以反过来做,只要其中一个函数为另一个函数做繁重的工作。两者都可以完成所有工作,但为什么呢?搞砸的地方是原来的两倍。