C++ 类 iostream 重载

标签 c++ overloading

我还在C++的基础学习过程中,在操作符重载部分,我无法理解iostream重载操作符的函数调用步骤。

我的困惑来自以下事实:当“重载 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, phone );'。同样在上面的示例中,它看起来像“cin >> phone;”这一行会被注意到并直接指向 friend 功能。按照我的理解,运算符(operator)调用“cin >> phone”将首先查看 PhoneNumber.h 声明。但是,运算符声明不在 PhoneNumber.h 中。它只是作为 friend 被“提及”。 (我对'friend'命令的理解是该类将简单地授予非成员函数(或类)访问其私有(private)数据或成员函数的权限。)因此,调用应该混淆编译器调用显式运算符函数以上代码,或 iostream 中的隐式运算符函数。

我想我的问题是: 1. 运算符“<<”和“>>”调用的格式与它们的声明方式有何不同? 2. .h 文件中未“声明”的运算符(operator)调用如何识别? C++ 如何知道跳过 .h 并直接跳转到用户定义的运算符函数?

最佳答案

您的问题中有一些明显的误解,但其余的我无法真正解析。希望以下内容足以解决您的疑问。

这个:

cin >> x;

是这个的语法糖(更像是你想象中的函数调用语法):

cin.operator>>(x);

或者有时(在这种情况下)这样:

operator>>(cin, x);

你不能随意为其中任何一个发明额外的参数!

关于C++ 类 iostream 重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29314516/

相关文章:

c++ - boost 变体 : Is there magic in the binding order?

java - RSA_verify 中预期的数据类型是什么,无法验证从 Java 生成的签名

Scala - 为什么不根据运行时类调用重载方法?

python - 将自身对象传递给需要此类型的函数

c# - 帮助解决 C# 中的隐式运算符重载

Scala双重定义(2个方法具有相同的类型删除)

c++ - C 或 C++。如何比较给定 char * 指针的两个字符串?

c++ - 我怎么知道音频文件的格式?

c++ - 解决模板中的循环依赖

C# 在运行时选择重载方法