07-重载的运算符
17.2.1 重载的<<运算符
本书常结合使用cout和<<运算符(插入(insertion)运算符):
int clients = 22;
cout << clients;
在C++中,与C一样,<<运算符的默认含义是按位左移运算符(参见附录E)。表达式x<<3的意思,将x的二进制表示中所有的位向左移动3位。显然,这与输出的关系不大。但ostream类重新定义了<<运算符,方法是将其重载为输出。在这种情况下,<<叫作插入运算符,而不是左移运算符(左移运算符由于其外观(像向左流动的信息流)而获得这种新角色)。插入运算符被重载,使之能够识别C++中所有的基本类型:
- unsigned char;
- signed char;
- char;
- short;
- unsigned short;
- int;
- unsiged int;
- long;
- unsigned long;
- long long(C++11);
- unsigned long long(C++11);
- float;
- double;
- long double。
对于上述每种数据类型,ostream类都提供了operator<<()函数的定义(第11章讨论过,名称中包含运算符的函数用于重载该运算符)。因此,如果使用下面这样一条语句,而value是前面列出的类型之一,则C++程序将其对应于有相应的特征标的运算符函数:
cout << value;
例如,表达式cout<<88对应于下面的方法原型:
ostream & operator<<(int);
该原型表明,operator<<()函数接受一个int参数,这与上述语句中的88匹配。该原型还表明,函数返回一个指向ostream对象的引用,这使得可以将输出连接起来,如下所示:
cout << "I'm feeling sedimental over " << boundary << "\n";
如果您是C语言程序员,深受%类型说明符过多、说明符类型与值不匹配时将发生问题等痛苦,则使用cout非常简单(当然,由于有cin,C++输入也非常简单)。
1.输出和指针
ostream类还为下面的指针类型定义了插入运算符函数:
- const signed char *;
- const unsigned char *;
- const char *;
- void *。
不要忘了,C++用指向字符串存储位置的指针来表示字符串。指针的形式可以是char数组名、显式的char指针或用引号括起的字符串。因此,下面所有的cout语句都显示字符串:
char name[20] = "Dudly Diddlemore";
char * pn = "Violet D'Amore";
cout << "Hello!";
cout << name;
cout << pn;
方法使用字符串中的终止空字符来确定何时停止显示字符。
对于其他类型的指针,C++将其对应于void *,并打印地址的数值表示。如果要获得字符串的地址,则必须将其强制转换为其他类型,如下面的代码片段所示:
int eggs = 12;
char * amount = "dozen";
cout << &eggs; // prints address of eggs variable
cout << amount; // prints the string "dozen"
cout << (void *) amount; // prints the address of the "dozen" string
2.拼接输出
插入运算符的所有化身的返回类型都是ostream &。也就是说,原型的格式如下:
ostream & operator<<(type);
(其中,type是要显示的数据的类型)返回类型ostream &意味着使用该运算符将返回一个指向ostream对象的引用。哪个对象呢?函数定义指出,引用将指向用于调用该运算符的对象。换句话说,运算符函数的返回值为调用运算符的对象。例如,cout << “potluck”返回的是cout对象。这种特性使得能够通过插入来连接输出。例如,请看下面的语句:
cout << "We have " << count << " unhatched chickens.\n";
表达式cout << “We have”将显示字符串,并返回cout对象。至此,上述语句将变为:
cout << count << " unhatched chickens.\n";
表达式cout<<count将显示count变量的值,并返回cout。然后cout将处理语句中的最后一个参数(参见图 17.4)。这种设计技术确实是一项很好的特性,这也是前几章中重载<<运算符的示例模仿了这种技术的原因所在。