C++输出时指针类型自动转换为bool类型输出的一个小疑问

今天翻看自己写的一篇博客,有关一条常见的const_cast转换的“BUG”解释 ,那篇博客最后留了一个疑问,为什么cout << &a 之后,输出的是1?(a为volatile const int类型)

当时猜想编译器把&a当做bool类型输出了,具体原因不清楚,当时也没在意。


今天翻看string类型的size函数和length函数的区别(详情参见string类的size与length的区别),原博主中记载,定义string类型的变量s,若使用cout输出s.size或s.length,则会调用ostream& operator < <(ostream&, bool)重载操作符,导致将该函数地址按bool类型变量输出。但该博主也未解释情况。

但同时还有人表示,cout<<s.at 则会报错。这究竟是为什么呢?


将上述论述写一个小程序验证(VC6.0中运行):

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s = "asd";
	cout << s << endl;
	cout << "s.length(): " << s.length() << endl;   // 输出为3
	cout << "s.size(): "   << s.size()   << endl;   // 输出为3
	cout << "s.length: "   << s.length   << endl;   // 输出为1
	cout << "s.size: "     << s.size     << endl;   // 输出为1
	cout << boolalpha;                              // 设置bool类型变量的输出格式
	cout << 1 << endl;	                            // 输出为1,用于验证对"1"输出与对"s.length"输出的差异
	cout << s.length << endl;                       // 输出为true
	cout << s.size << endl;                         // 输出为true
    return 0;
}

首先,发现s.length()与s.size()返回值相同(length()多用来求长度,size()则用来求容器中的元素数量,在string类型中返回值相同,但其代表意义不同)

第二,发现类的成员函数地址在输出时会被自动转换成bool类型输出

那么问题来了,“但同时还有人表示,cout<<s.at 则会报错。这究竟是为什么呢?”

我观察了一下,程序中加入cout << s.at 后果然会报错。我想不应该呀,即使是一个地址,即使你编译器不按套路出牌,即使转换成其他类型,也不应该报错呀。

看了一下错误说明:

error C2679: binary '<<' : no operator defined which takes a right-hand operand of type '' (or there is no acceptable conversion)

原来编译器根本不知道这是一个指针类型,汗!

仔细一想,明白了,s.at是一个重载的成员函数,如果不给定参数,编译器无法判断到底使用哪个函数,所以有了上面的错误说明。

后来找到了一个没有重载的函数:s.c_str(),将其添加到最后一行:

cout << s.c_str << endl;

编译器果然没报错,高高兴兴地地输出了一个true!


So,一个问题解决了:只有当编译器真正明白操作数是什么类型的时候,才会进行输出,所以重载函数的地址是无法进行直接输出的,因为只靠函数名根本无法确定地址。

当然有一个办法,就是将某一个重载函数的地址赋给指向该重载函数类型的指针类型变量,这样就能顺利输出了(但仍然是按bool型输出)


但最重要的一个问题还在:在使用cout进行输出时,什么样的指针类型会被自动转换成bool类型?为什么会发生如此的转换?——暂无定论,也希望大家帮忙解答。


备注:在我第一次写该文章时,有一个用词不是很妥帖:在我论述 cout << s.size << endl;时,我说我对“指向函数的指针”进行输出。但实际上在输出语句中,操作数是函数名,并不是一个指针变量。而函数名虽然代表该函数的地址,但却并不是(指针)变量。就像在输出语句中cout一个整型数组的数组名,输出的是数组中第一个元素的地址。这个地址确实无需类型转换便可赋值给一个指向整型变量的指针(变量),然而数组名并不是一个变量,它不在内存中存放,而是在编译时被转换为地址,在汇编代码和机器码中被使用。而指针变量却是真实存在于内存之中的。所以第二遍我将类似论述全部修改了一遍。

另:如果单讲“指针”这个词,我认为是表示一种变量。即:指针的地位可以等同于“char型变量”但不能等同于“char”。我们常说“定义一个指针”,“有一个指针”,或“指针与数组不同”,这里指的指针应该指的是“指针变量”的意思。

在用词时,最好还是说清楚:是指针变量,还是指针类型。


以上。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值