【问题标题】:Why does calling cout.operator<<(const char*) print the address instead of the character string?为什么调用 cout.operator<<(const char*) 打印地址而不是字符串?
【发布时间】:2019-12-09 08:03:13
【问题描述】:

我正在探索 C++ 中的 ostream 类。我被cout 的字符串和整数数据类型的奇怪输出困住了。

当传递一个整数或浮点值时,输出正是我传递的。例如cout.operator&lt;&lt;(10); 打印10。但是当将字符串作为参数传递时,它会打印一些十六进制值:

#include <iostream>
#include <string>

using namespace std;

int main() {
        const char* str = "aia";
        cout.operator<<(str);
        return 0;
}

输出:0x4007e0

【问题讨论】:

  • 你为什么要这样直接使用operator&lt;&lt;?你想做什么?
  • @NicolBolas 我怀疑他们不知道该怎么做。
  • 我想了解操作符的级联实际上是如何工作的
  • 假设您没有特殊原因使用这种形式的运算符cout << str;,您就会看到预期的输出。
  • 我试过了,它打印了字符串,但我的问题是为什么它打印一些十六进制值,而它可以打印其他数据类型的相同结果

标签: c++ c++11 c++14


【解决方案1】:

当您执行cout.operator&lt;&lt;(str) 时,您调用coutoperator &lt;&lt; 成员函数。如果我们看看 member functions overloads cout 我们有什么

basic_ostream& operator<<( short value );
basic_ostream& operator<<( unsigned short value );

basic_ostream& operator<<( int value );
basic_ostream& operator<<( unsigned int value );

basic_ostream& operator<<( long value );
basic_ostream& operator<<( unsigned long value );

basic_ostream& operator<<( long long value );
basic_ostream& operator<<( unsigned long long value );

basic_ostream& operator<<( float value );
basic_ostream& operator<<( double value );
basic_ostream& operator<<( long double value );

basic_ostream& operator<<( bool value );

basic_ostream& operator<<( const void* value );

basic_ostream& operator<<( std::nullptr_t );

basic_ostream& operator<<( std::basic_streambuf<CharT, Traits>* sb);

basic_ostream& operator<<(
    std::ios_base& (*func)(std::ios_base&) );

basic_ostream& operator<<(
    std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&) );

basic_ostream& operator<<(
    std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );

如果您注意到,const char* 没有一个,但const void* 有一个。因此,您的 const char* 被转换为 const void* 并且该版本的函数打印指针所持有的地址。

您需要做的是调用operator&lt;&lt;non member function overload 并这样做您可以使用

cout << str;

【讨论】:

  • 始终使用cout &lt;&lt; X,切勿直接使用cout.operator&lt;&lt;(X)operator&lt;&lt;(cout, X)(除非您有充分的理由这样做)。让编译器根据上下文和数据类型决定调用哪一个。
  • @RemyLebeau 我已经删除了operator&lt;&lt;(cout, X) 电话。正如你所说,他们应该只使用运算符语法。
【解决方案2】:

问题在于,对于某些类型,operator&lt;&lt; 被重载为 ostream 的成员,而对于某些类型,它被重载为全局函数。对于const char*,它是一个全局函数,所以如果你想显式调用操作符函数,你必须写

operator<<(cout, str);

但是对于整数类型你必须写

cout.operator<<(num);

您发布的代码中发生的情况是 const void* 的重载被调用,这就是您看到十六进制数字的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多