怎么做cout<<实际上工作?

时间:2011-04-01 03:33:50

标签: c++ cout

我想知道std::cout如何能够使用<<

我的主要困惑在于std::cout是否是某事物的一个例子。基本上,<<是如何定义的?如果我为自定义类执行此操作,我需要某种类型的实例...

我可以看到将它实现为带有无效指针或其他东西的黑客攻击,但我希望看到它实际完成的方式。

这里有人知道吗? 感谢

1 个答案:

答案 0 :(得分:46)

std::coutstd::ostream的一个实例。 std::cout << "something"调用operator<<重载之一,就像std::ostream的任何实例一样。

它是“特殊的”,因为它引用了控制台,但它的行为与ofstreamostringstream完全相同。

编辑:链接就像它适用于任何其他运营商一样。考虑:

class MyType
{
    friend std::ostream& operator<<(std::ostream& target, const MyType& source);
    int val;
public:
    MyType()
        : val(0)
    { }
    MyType& Add(int toAdd)
    {
        val += toAdd;
        return *this;
    }
};

MyType& operator+(MyType& target, int toAdd)
{
    return target.Add(toAdd);
}

std::ostream& operator<<(std::ostream& target, const MyType& source)
{
    target << source.val;
    return target; //Make chaining work
}

int main()
{
    MyType value1;
    value1 + 2 + 3 + 4;
    std::cout << value1 << " and done!" << std::endl;
}

在这种情况下,MyType上+ s的链接工作的原因与<<std::ostream之上工作的原因相同。 +<<都是左关联的,这意味着它们是从左到右进行评估的。对于重载运算符,运算符将替换为等效函数调用。

EDIT2 :更详细一点:

假设您是编译器并且正在解析

std::cout << value1 << " and done!" << std::endl;

首先,<<是左关联的,所以你从左边开始。您评估第一个<<并将其转换为函数调用:

operator<<(std::cout, value1) << " and done!" << std::endl;

然后您看到您再次拥有std::ostream(调用operator<<的结果)和char *,您再次进入函数调用:< / p>

operator<<(operator<<(std::cout, value1)," and done!") << std::endl;

等等,直到你处理完整个陈述。