[英]C++ class iostream overloading
我仍处于C ++的基础学习过程中,在我讨论运算符重载部分时,我无法理解iostream重载运算符的函数调用步骤。
我的困惑来自这样一个事实:当“通过Friend命令在我的类定义之外定义重载iostreeam函数”时,以下C ++代码可以区分基本类型的数据iostream调用和类iostream调用。 请看下面的例子。
#ifndef PHONENUMBER_H
#define PHONENUMBER_H
#include <iostream>
#include <string>
class PhoneNumber
{
friend std::ostream &operator<<( std::ostream &, const PhoneNumber & )
friend std::istream &operator>>( std::istream &, PhoneNumber & )
private:
std::string areaCode;
std::string exchange;
std::string line;
};
#endif
现在,重载函数定义。
#include <iomanip>
#include "PhoneNumber.h"
using namespace std;
ostream &operator<<( ostrea &output, const PhoneNumber &number )
{
output << "(" number.areaCode << ")" << number.exchange << "-" << number.line;
return output;
}
istream &operator>>( istream &input, PhoneNumber &number )
{
input.ignore();
input >> setw( 3 ) >> number.areaCode;
input.ignore( 2 );
input >> setw( 3 ) >> number.exchange;
input.ignore();
input >> setw( 4 ) >> number.line;
return input;
}
现在的主要功能。
#include <iostream>
#include "PhoneNumber.h"
using namespace std;
int main()
{
PhoneNumber phone;
cout << "Enter phone number in the form (123) 456-7890" << endl;
cin >> phone;
cout << "The phone number entered was: ";
cout << phone << endl;
}
据我了解,通常函数调用(甚至是运算符重载函数)必须遵循声明格式。 因此,要调用重载<<(或>>)运算符,用户将必须编写如下代码:'ostream a;' 后跟“ cin >>(a,电话);”。 同样在上面的示例中,它看起来像“ cin >> phone;”行。 将被注意并直接指向朋友功能。 按照我的理解,按照操作步骤,操作员呼叫“ cin >>电话”将首先查看PhoneNumber.h声明。 但是,运算符声明不在PhoneNumber.h中。 它只是被“提及”为朋友。 (我对'friend'命令的理解是,该类将简单地授予非成员函数(或类)对其私有数据或成员函数的访问权限。)因此,该调用应混淆编译器以在其中调用显式运算符函数以上代码或iostream中的隐式运算符函数。
我想我的问题是:1.运算符“ <<”和“ >>”调用的格式与声明的格式不同吗? 2.在.h文件中未“声明”时,如何识别操作员呼叫? C ++如何知道跳过.h并直接跳入用户定义的运算符函数?
您的问题中存在一些明显的误解,但其余的我无法真正解析。 希望以下内容足以解决您的查询。
这个:
cin >> x;
是语法糖(更像是您正在想象的函数调用语法):
cin.operator>>(x);
有时(在这种情况下)是这样的:
operator>>(cin, x);
您不能为其中任何一个随机地创造一个额外的参数!
因为它们被声明为“运算符”功能。 与您在问题中所写的相反,这不是“正常”功能。 正常的函数声明为: std::ostream &<<(std::ostream &, const Phonenumber &)
(我认为不会编译)。 但是您将其声明为std::ostrean &operator<<(std::ostream &, const Phonenumber &)
,这使其成为运算符重载。
这似乎确实很棘手,但这是因为您在编译器中有一个编译步骤和一个链接步骤。 在编译时,编译器会将您的好友函数声明解析为您在另一个文件中编写的流运算符。 它们匹配,因为函数声明相同,并且它们被声明为朋友函数。 在链接时(这是构建最终程序的地方),如果您已告诉链接器组合所有这些文件,则链接器将尝试查找与主循环内使用的函数匹配的对象。 如果找不到它们,您将得到类似: Undefined reference to ...
。
由于运算符调用是在头文件中声明的(您说不是,但实际上是声明为朋友函数),因此编译器和链接器都将成功。 编译器不会告诉您: Use of undeclared function ...
而链接程序不会告诉您: Undefined reference to...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.