У меня проблемы с оператором -
На самом деле, у вас есть еще немного проблем! Уже operator++
не будет работать, как ожидалось. Попробуйте:
Time t(0, 59, 59);
++t;
Как только вы увеличиваете секунды с переполнением, следующее, которое может переполниться, - это минуты, поэтому вам нужно сначала проверить их!
++seconds;
if(seconds == 60)
{
seconds = 0;
++minutes;
// only, if minutes were incremented, they can overflow, so check only here needed
if(minutes == 60)
{
minutes = 0;
// open: how do you want to handle hours overflowing?
// variant 1: just go on, counting 23, 24, 25, ...
++hours;
// variant 2: restart at 0:
hours = (hours + 1) % 24;
// variant 3 (my favourite): rember in a flag that we overflowed
// (and have a getter for so that user can check):
isWrapAround = hours == 23; // new member variable of type bool
hours = (hours + 1) % 24;
}
}
Аналогично, вы бы обработали operator--
, просто заменив каждый случай ++
на --
и настроив обнаружение переполнения на обнаружение переполнения. Осторожнее с последним: ваш исходный код не смог правильно определить недостаточное количество:
--seconds;
if(seconds == 0)
Это уже уменьшит минуты, когда у нас фактически останется 1 секунда, но 00:00:00 - правильное время! Поэтому вам нужно либо проверить 0 перед уменьшением (if(seconds-- == 0)
, либо проверить отрицательные значения впоследствии (--seconds; if(seconds == -1)
или if (seconds < 0)
). С этим исправлением += 59
больше не будет корректным либо вам понадобится либо += 60
, либо, предпочтительно, = 59
.
Обычно , операторы предварительного увеличения и -decrement возвращают ссылку на текущий объект. Это позволило бы е. г. ++(++time)
:
Time& Time::operator++()
{
// increment as described
return *this;
}
Операторы пост-инкремента и -декремента очень странные ... Пожалуйста, подтвердите, если это действительно задача - увеличивать / уменьшать минуты (если так, я могу только трясти головой учитель ...). Это будет большим сюрпризом для всех, так как операторы ведут себя совершенно иначе, чем обычно! Последний будет:
Time operator++(int)
{
Time tmp(*this);
++*this;
return tmp;
}
Если вы действительно, действительно увеличите минуты (обратите внимание на иронию: операторы после X-кремации на самом деле ведут себя как до-X-кремация, по крайней мере, так выглядит ваш первоначальный подход): просто оставьте секунды нетронутым. Все, что вам тогда нужно в постоператорах, это body самого внешнего, если в соответствующих предварительных вариантах. Затем они могут быть переписаны (чтобы избежать дублирования кода) как:
++seconds;
if(seconds == 60)
{
seconds = 0;
*this++; // use post-fix to adjust minutes...
}
Наконец: сравнение: К сожалению, у нас еще нет C ++ 20, в противном случае мы просто могли бы реализовать оператор космического корабля (<=>
) ... Неважно, мы все равно можем вместо этого использовать обычную функцию и используйте это в операторах:
int Time::compare(Time const& other) const
{
// most relevant are hours, if these differ, values of minutes or
// seconds don't matter any more...
int result = hours - other.hours;
if(result == 0)
{
// so hours are the same...
// minutes then are relevant next
result = minutes - other.minutes;
if(result == 0)
result = seconds - other.seconds;
}
return result;
}
Тогда все операторов, которые будут реализованы, будут выглядеть так:
bool Time::operator@(Time const& other) const
{
return compare(other) @ 0;
}
, где @
обозначает всех ваших необходимых операторов (==
, !=
, <
, <=
, >
, >=
).
Бонус: запоминание переполнения без отдельного флага:
Вам больше не понадобится другая переменная, но она требует более сложной логики.
Сначала, если оставить значение -1 (operator--
), это будет означать, что произошел переход. Соответственно, геттер для циклического преобразования будет return hours == -1;
.
В любом другом месте, где мы ранее использовали hours
напрямую, мы теперь использовали бы метод получения, который будет выглядеть следующим образом:
int Time::getHours() const
{
return hours + (hours == -1);
}
Вычислить значение для приращения немного сложнее:
hours = (getHours() + 1) % 24 - (hours == 23);