简体   繁体   English

C ++类iostream重载

[英]C++ class iostream overloading

I'm still in the basic learning process of C++, and as I go though operator overloading part, I could not understand the function call steps of iostream overload operators. 我仍处于C ++的基础学习过程中,在我讨论运算符重载部分时,我无法理解iostream重载运算符的函数调用步骤。

My confusion is coming from the fact that C++ code below can distinguish between the fundamental-type data iostream call and class iostream call when 'the overload iostreeam functions are defined outside of my class definition via friend command.' 我的困惑来自这样一个事实:当“通过Friend命令在我的类定义之外定义重载iostreeam函数”时,以下C ++代码可以区分基本类型的数据iostream调用和类iostream调用。 Please take a look at below example. 请看下面的例子。

#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

Now the overload function definition. 现在,重载函数定义。

#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;
}

Now the main function. 现在的主要功能。

#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;
}

Per my understanding, normally a function call (even operator overload functions) is obligated to follow the declaration format. 据我了解,通常函数调用(甚至是运算符重载函数)必须遵循声明格式。 So to call overload << (or >>) operator functions, the user would have to write lines like this: 'ostream a;' 因此,要调用重载<<(或>>)运算符,用户将必须编写如下代码:'ostream a;' followed by 'cin >> ( a, phone );'. 后跟“ cin >>(a,电话);”。 Also in above example, it appears like the line 'cin >> phone;' 同样在上面的示例中,它看起来像“ cin >> phone;”行。 would be notice and directed straight to the friend function. 将被注意并直接指向朋友功能。 To follow the steps per my understanding, the operator call 'cin >> phone' will first look at PhoneNumber.h declaration. 按照我的理解,按照操作步骤,操作员呼叫“ cin >>电话”将首先查看PhoneNumber.h声明。 However, operator declaration is not in PhoneNumber.h. 但是,运算符声明不在PhoneNumber.h中。 It is only 'mentioned' as a friend. 它只是被“提及”为朋友。 (My understanding of 'friend' command is that the class will SIMPLY grant a non-member function (or class) access to its private data or member functions.) Therefore, the call should confuse the compiler to call either the explicit operator function in above code, or implicit operator function in iostream. (我对'friend'命令的理解是,该类将简单地授予非成员函数(或类)对其私有数据或成员函数的访问权限。)因此,该调用应混淆编译器以在其中调用显式运算符函数以上代码或iostream中的隐式运算符函数。

I guess my questions are: 1. How do the operator '<<' and '>>' calls have different format than how they are declared? 我想我的问题是:1.运算符“ <<”和“ >>”调用的格式与声明的格式不同吗? 2. How can the operator calls be recognized when it is not 'declared' in .h file? 2.在.h文件中未“声明”时,如何识别操作员呼叫? How does C++ know to skip .h and jump right into user defined operator functions? C ++如何知道跳过.h并直接跳入用户定义的运算符函数?

There are a few clear misunderstandings in your question but the rest I can't really parse. 您的问题中存在一些明显的误解,但其余的我无法真正解析。 Hopefully the following will be enough to resolve your query. 希望以下内容足以解决您的查询。

This: 这个:

cin >> x;

is syntactic sugar for this (which is more like the function call syntax you are imagining): 是语法糖(更像是您正在想象的函数调用语法):

cin.operator>>(x);

or sometimes (and in this case) this: 有时(在这种情况下)是这样的:

operator>>(cin, x);

You can't randomly invent an extra argument for either of those! 您不能为其中任何一个随机地创造一个额外的参数!

  1. Because they are declared as "operator"-functions. 因为它们被声明为“运算符”功能。 That is not, in contrast of what you're writing in your question, a "normal" function. 与您在问题中所写的相反,这不是“正常”功能。 A normal function declaration would be: std::ostream &<<(std::ostream &, const Phonenumber &) (which I think wouldn't compile). 正常的函数声明为: std::ostream &<<(std::ostream &, const Phonenumber &) (我认为不会编译)。 But you declare it as std::ostrean &operator<<(std::ostream &, const Phonenumber &) , which makes it an operator overload. 但是您将其声明为std::ostrean &operator<<(std::ostream &, const Phonenumber &) ,这使其成为运算符重载。

  2. That seems indeed tricky, but that's because you have a compile-step and link-step in the compiler. 这似乎确实很棘手,但这是因为您在编译器中有一个编译步骤和一个链接步骤。 At compile time, the compiler will resolve your friend function declarations to the streaming operator functions you have written in another file. 在编译时,编译器会将您的好友函数声明解析为您在另一个文件中编写的流运算符。 They match, because the function declarations are the same and they were declared as friend functions. 它们匹配,因为函数声明相同,并且它们被声明为朋友函数。 At link-time (this is where you're final program is built), if you've told the linker to combine all those files, the linker will try to find a match for the functions that are used inside the main loop. 在链接时(这是构建最终程序的地方),如果您已告诉链接器组合所有这些文件,则链接器将尝试查找与主循环内使用的函数匹配的对象。 If they're not found, you'll get something like : Undefined reference to ... . 如果找不到它们,您将得到类似: Undefined reference to ...

    Since the operator calls are declared in the header-file (you say they're not, but they are - they're simply declared as friend functions), both the compiler and the linker will succeed. 由于运算符调用是在头文件中声明的(您说不是,但实际上是声明为朋友函数),因此编译器和链接器都将成功。 The compiler will not tell you: Use of undeclared function ... and the linker will not tell you: Undefined reference to... 编译器不会告诉您: Use of undeclared function ...而链接程序不会告诉您: Undefined reference to...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM