C++ 运营商>&燃气轮机;超载

C++ 运营商>&燃气轮机;超载,c++,operator-overloading,C++,Operator Overloading,我正在使用运算符重载实现一个复数。在程序中,用户输入的复数形式始终为: a + bi 所以,举个例子 25.0 + 3.6i 假设用户将始终输入复数的实部和虚部,例如,用户将输入“5+0i”(而不是“5”)或“0-6.2i”(而不是“-6.2i”) 我的问题是在main()中有以下代码: ComplexNumber c1; cin >> c1; cout << c1; …当我在运行时在提示符中输入“4.2+8.3i”时 下面是我的操作符>类的实现: istream

我正在使用运算符重载实现一个复数。在程序中,用户输入的复数形式始终为:

a + bi
所以,举个例子

25.0 + 3.6i
假设用户将始终输入复数的实部和虚部,例如,用户将输入“5+0i”(而不是“5”)或“0-6.2i”(而不是“-6.2i”)

我的问题是在main()中有以下代码:

ComplexNumber c1;
cin >> c1;
cout << c1;
…当我在运行时在提示符中输入“4.2+8.3i”时

下面是我的
操作符>
类的实现:

istream & operator>>(istream & in, ComplexNumber & n) {
    string real;
    string imag;
    bool done = false;
    int sign = 1;

    string num;
    in >> num;

    int length;
    for (int i = 0; i < num.length(); i++) {
        if (num.at(i) == 'i') {
            imag = num.substr((i - length), i);
        }
        else if (num.at(i) == '-') {
            sign = -1;
        }
        else if (num.at(i) == ' ') {
            if (!done) {
                real = num.substr(i);
                done = true;
            }
            length = 0;
        }
        length++;
    }

    n = ComplexNumber(atof(real.c_str()), atof(imag.c_str()) * sign);
    return in;
}
ostream & operator<<(ostream & out, const ComplexNumber & n) {
    n.print(out);
    return out;
}
istream&operator>>(istream&in,ComplexNumber&n){
字符串实数;
字符串图像;
bool done=false;
int符号=1;
字符串数;
在>>num中;
整数长度;
对于(int i=0;i
下面是我对
操作符这一部分的实现:

string num;
in >> num;

它只从输入中读取一个单词。你需要多次调用它来阅读类似于
4.2+8.3i
,它有三个单词。

本质上你的
操作符>>
太复杂了,甚至不能正确处理错误。您不应该首先将值读入字符串–直接读入数字。此外,在每次读取操作之后,您需要检查(并可能设置)流的状态

istream& operator >>(istream& in, ComplexNumber& value) {
    int re;
    if (not (in >> re)) {
        return in;

    char pm;
    if (not (in >> pm) or (pm != '+' and pm != '-') {
        in.setstate(ios::failbit);
        return in;
    }

    int im;
    if (not (in >> im))
        return in;

    char i;
    if (not (in >> i) or i != 'i') {
        in.setstate(ios::failbit);
        return in;
    }

    value = ComplexNumber {re, (pm == '-' ? -im : im)};
    return in;
}
(我使用C++11初始化器是因为我很懒……)

是的,通过将整个读数拉入一个单链表达式,可以写得更短:

istream& operator >>(istream& in, ComplexNumber& value) {
    int re;
    int im;
    char pm;
    char i;

    if (not (in >> re >> pm) or
        (pm != '+' and pm != '-') or
        not (in >> im >> i) or
        i != 'i')
    {
        in.setstate(ios::failbit);
        return in;
    }

    value = ComplexNumber {re, (pm == '-' ? -im : im)};
    return in;
}

这是否更好取决于观众。就我个人而言,我确实觉得它比第一个版本更具可读性。一个更结构化的替代方案(对于这样一个简单的情况来说,这可能是多余的)是允许非常优雅的解析器构造。

你不是已经问过这个问题了吗?我问了一些类似的问题,但并不简洁。所以我删掉了那个,提出了一个更合适的问题。我不确定这是一个简洁的好例子……怎么样?(编辑:添加链接)此外,您应该编辑原始问题,而不是删除它并创建一个新问题。您是说“in>>num”在用户点击enter键之前不接受输入?它在任何空白处分开?您应该使用INSTEAD来解释复数{re,(pm='-'?-im:im)}吗?正如我所说的,这是一个C++11风格的初始化器,它相当于您的构造函数(我懒得在测试代码中编写它)。
string num;
in >> num;
istream& operator >>(istream& in, ComplexNumber& value) {
    int re;
    if (not (in >> re)) {
        return in;

    char pm;
    if (not (in >> pm) or (pm != '+' and pm != '-') {
        in.setstate(ios::failbit);
        return in;
    }

    int im;
    if (not (in >> im))
        return in;

    char i;
    if (not (in >> i) or i != 'i') {
        in.setstate(ios::failbit);
        return in;
    }

    value = ComplexNumber {re, (pm == '-' ? -im : im)};
    return in;
}
istream& operator >>(istream& in, ComplexNumber& value) {
    int re;
    int im;
    char pm;
    char i;

    if (not (in >> re >> pm) or
        (pm != '+' and pm != '-') or
        not (in >> im >> i) or
        i != 'i')
    {
        in.setstate(ios::failbit);
        return in;
    }

    value = ComplexNumber {re, (pm == '-' ? -im : im)};
    return in;
}