为什么显式调用operator<<在std :: cout导致意外输出?

时间:2012-12-24 00:23:18

标签: c++ string operator-overloading iostream

我很清楚,如果我明确地operator<< std::cout,我会发生什么,因为我了解到a.operator()a()完全相同。所以我这样做,它打印出一些奇怪的东西:

#include <iostream>

using std::cout;

int main()
{
    cout.operator<<("Hello World");
}
  

Output: 0x80486a0

奇怪的是,它会输出一个地址(地址可能会有所不同,但它应该仍然是一个地址)。我认为这是字符串的地址所以我尝试解除引用它以使其输出字符串:

*( cout.operator<<("Hello World") );

但是我收到了很长的错误

  

no match for operator* in '*std::cout.std::basic_ostream<...

我认为这很奇怪。 std::cout定义中的任何内容都不会让我相信这会导致任何不同的行为;同样明确调用运算符函数没有区别(或者至少应该)。

那为什么我得到这个输出?为什么在显式调用运算符时我收到的是地址而不是字符串本身?这甚至是内存中的地址还是垃圾输出?任何回复都表示赞赏。

2 个答案:

答案 0 :(得分:22)

内置字符串的输出运算符,即以char const*为参数的on,不是std::ostream的成员。采用char const*的运算符是非成员函数,将被称为

operator<< (std::cout, "Hello World");

然而,有一个成员使用void const*使用十六进制表示法格式化指针的值。将任何指针明确传递给operator<< ()的成员std::ostream时,此成员是最佳匹配。

取消引用operator<<()的结果不起作用:运算符返回std::ostream&,其中没有一元operator*()重载。如果你打算取消引用这个论点,你可以这样称呼它:

std:cout.operator<< (*"Hello World");

但是,这只会将字符串文字的char const*衰减,从而产生一个单独的字符H。字符输出函数也不是成员函数,而整数的输出运算符是,即它将打印字符值H。对于使用ASCII的系统,它将是72

答案 1 :(得分:7)

我认为这里的问题是将C样式字符串打印到输出流的operator <<实际上是自由函数,而不是basic_ostream的成员函数。但是,basic_ostream确实具有operator<<函数,该函数接收void*并打印出其地址。因此,如果您明确尝试将operator<<作为成员函数进行调用,那么您将调用打印出C样式字符串地址的版本,而不是将字符串打印出来的自由函数。

你可以通过调用

来看到这一点
operator<< (std::cout, "Hello, world!");

实际上 打印字符串。

希望这有帮助!