Почему моя строка печатается не в том месте? - PullRequest
0 голосов
/ 22 мая 2019

Я ожидаю этот вывод:

Дополнение: 5/6/92 + 5/6/92 = 10/12/184

но я получаю этот вывод:

5/6/92 + 5/6/92 = Дополнение: 10/12/184

Почему это происходит?

Как я могу решить эту проблему без изменения основной функции?

#include <iostream>

using namespace std;

class Date {
    int mo, da, yr;
    public:
        Date(int m, int d, int y) {
            mo = m;
            da = d;
            yr = y;
        }
    friend ostream & operator << (ostream & os,
        const Date & dt);
    Date operator + (const Date & dat) const {
        Date newDate(0, 0, 0);
        newDate.mo = dat.mo + mo;
        newDate.da = dat.da + da;
        newDate.yr = dat.yr + yr;
        cout << dat << "+" << mo << "/" << da << "/" << yr << "=";
        return newDate;
    }
};

ostream & operator << (ostream & os,
    const Date & dt) {
    os << dt.mo << '/' << dt.da << '/' << dt.yr;
    return os;
}

int main() {
    Date dt(5, 6, 92);
    cout << "Addition: " << dt + dt;
}

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Проблема в том, что dt + dt оценивается до выполнения cout << "Addition: ".

std::ostream не имеет методов с одним параметром operator<<, которые принимают const char[] или Date в качестве входных данных, поэтому вместо этого он должен вызывать перегрузки, не являющиеся членами operator<<. Таким образом, выражение cout << "Addition: " << dt + dt; в конечном итоге выглядит для компилятора следующим образом:

operator<<(operator<<(cout, "Addition: "), dt + dt);

Во внешнем вызове operator<< ваш компилятор выбирает оценку второго параметра (dt + dt) перед вычислением первого параметра (operator<<(cout, "Addition: ")).

Вы не сможете получить желаемый результат, не изменив main(), чтобы изменить порядок оценок, чтобы принудительно установить желаемый порядок, например:

#include <iostream>
using namespace std;

class Date {
    int mo, da, yr;

    public:
        Date(int m, int d, int y) {
            mo = m;
            da = d;
            yr = y;
        }

    friend ostream & operator << (ostream & os, const Date & dt) {
        os << dt.mo << '/' << dt.da << '/' << dt.yr;
        return os;
        }

    Date operator + (const Date & dat) const {
        Date newDate(dat.mo + mo, dat.da + da, dat.yr + yr);
        cout << *this << "+" << dat << "=";
        return newDate;
    }
};

int main() {
    Date dt(5, 6, 92);
    cout << "Addition: ";
    cout << dt + dt;
}

Хотя, как правило, было бы лучше вообще удалить выходную печать из вашего operator+, просто дайте main() распечатать, как хотите:

#include <iostream>
using namespace std;

class Date {
    int mo, da, yr;

    public:
        Date(int m, int d, int y) {
            mo = m;
            da = d;
            yr = y;
        }

    friend ostream & operator << (ostream & os, const Date & dt) {
        os << dt.mo << '/' << dt.da << '/' << dt.yr;
        return os;
        }

    Date operator + (const Date & dat) const {
        return Date(dat.mo + mo, dat.da + da, dat.yr + yr);
    }
};

int main() {
    Date dt(5, 6, 92);
    Date sum = dt + dt;
    cout << "Addition: " << dt << "+" << dt << "=" << sum;
}
0 голосов
/ 22 мая 2019

Давайте посмотрим на cout << "Addition: " << dt + dt;.

То, что происходит, dt + dt оценивается ПЕРВЫЙ, который содержит cout внутри оценки.После этого программа печатает "Addition: " и, наконец, результат предыдущей оценки.

Вы видите проблему здесь?Это не чтение слева направо, как это делает человек, а оценка, когда он видит оператор +.Он оценивает все, что должно быть обработано (и вызывает cout, который находится внутри +), а затем, получив все ответы, он отправляет на печать слева направо.

Наличие оператора print внутриОператоры, как правило, не очень хорошая идея, может быть, просто для отладки.Вы должны удалить это.В вашем случае просто напечатайте то, что вы хотите, прежде чем распечатать результат.Если вы хотите, вы можете даже создать функцию, которая (1) печатает информацию об операции и операнды (2) вызывает оператор (3) печатает результат.Например:

// Don't forget to remove cout statements from the overloaded +
void printThenAdd(Date dt0, Date dt1) {
    cout << "Addition: ";
    cout << dt0.mo << '/' << dt0.da << '/' << dt0.yr << " + ";
    cout << dt1.mo << '/' << dt1.da << '/' << dt1.yr;
    cout << " = " << dt0 + dt1 << endl;
}

Удачи!Я вижу, как это может сбить с толку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...