简体   繁体   English

重载运算符>>和<<,以便它接受用户定义的对象

[英]Overloading operator >> and << so that it accepts user-defined object

I've got an object (of class myObj) that contains multiple strings (a string pointer). 我有一个包含多个字符串(字符串指针)的对象(myObj类)。 I want to overload the >>operator so that I can read in multiple strings at a time. 我想重载>>运算符,以便一次可以读取多个字符串。

This overloaded operator functions accept statements like: 此重载的运算符函数接受以下语句:

cin >> str; cin >> str;

cout << str; cout << str;

The only problem is that when I fill in a series of strings, it seems that only the first string gets correctly processed in the stream. 唯一的问题是,当我填充一系列字符串时,似乎只有第一个字符串在流中得到了正确处理。

To insert: 要插入:

istream &operator>>(istream &is, myObj &obj)
{
    std::string line;

    while (true)
    {
        std::getline(is, line);
        if (not is)
            break;
        obj.add(line);
        is >> line;
    }

    return is; 
}

To extract 提取

ostream &operator<<(ostream &os, myObj const &obj)
{
    for(size_t idx = 0; idx != obj.size(); ++idx) 
        os << obj[idx];
    return os;
}

The code compiles fine but when I cout the object only the first string is printed and the other strings are omitted. 代码可以正常编译,但是当我关闭对象时,仅打印第一个字符串,而忽略其他字符串。

So when I provide cin with: 因此,当我为cin提供以下功能时:

Hi
Stack
Exchange

only Hi will be displayed. 仅显示Hi。

Does anyone know why this happens? 有谁知道为什么会这样吗?

Thanks in advance! 提前致谢!

PS I am new to Stack Exchange and I am working hard to formulate the problems as best as I can :) PS:我是Stack Exchange的新手,我正在努力尽最大可能解决问题:)

Your loop will work like that: 您的循环将像这样工作:

std::getline(is, line);

Extracts and stores "Hi" in line , extracts the newline 提取和存储在“嗨” line ,提取换行符

obj.add(line);

Adds "Hi" to obj 将“ Hi”添加到obj

is >> line;

Extracts and stores "Stack" in line , does not extracts the following newline 提取和存储“堆栈”的line ,不会提取后面的换行符

std::getline(is, line);

Extracts and stores an empty string in line , because next read char is a newline 提取并line存储一个空字符串,因为下一个读取的char是换行符

obj.add(line);

Adds empty string "" to obj 将空字符串“”添加到obj

is >> line;

Extracts and stores "Exchange" in line 在提取和存储“交换” line

std::getline(is, line);

Extracts nothing (end of input stream) 不提取任何内容(输入流的末尾)

if (not is)
    break;

Then the stream is at end, your loop exits. 然后流结束,您的循环退出。

Conclusion : you stored only Hi and an empty string 结论:您只存储了Hi和一个空字符串

is >> line puts a leading newline in the stream which is being read by std::getline() during the following loop. is >> line一个换行符放在流中,该流在以下循环中由std::getline()读取。 Because std::getline() stops input when it finds a newline, this reads an empty string into line and thus the stream is put into an error state which the loop responds to by breaking out of it. 因为std::getline()在找到换行符时会停止输入,所以它将空字符串读入line ,从而使流进入错误状态,循环通过中断来响应该错误状态。

There doesn't seem to be a need for that last read. 似乎不需要最后阅读。 You can remove it. 您可以删除它。

Also, this is a more idiomatic way to loop with input. 同样,这是一种循环使用输入的更惯用的方法。 This way you don't have to check the state of the stream within the loop body: 这样,您不必检查循环体内的流状态:

for (std::string line; std::getline(is, line); )
{
    obj.add(line);
}

And since there's only one token per line, you can use a formmatted extractor: 由于每行只有一个令牌,因此可以使用带格式的提取器:

for (std::string word; is >> word; )
{
    obj.add(word);
}

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

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