运算符重载逻辑问题

时间:2019-04-16 09:58:14

标签: c++ oop operator-overloading overloading

我们在课堂上的其中一项任务是创建一个程序,该程序使用对象显示小时,分钟和秒。使用这些数字,我们现在必须使各种运算符过载,这将使秒/分钟增加1,并使用++和-减少它们。我在-运算符方面遇到了一些麻烦,因为如果我输入0分钟,它将无法按预期工作,并且它减少了返回分钟的时间,例如128分钟。我刚开始时,我将非常感谢您的帮助。

然后第二部分使用其他运算符(> <> = <= ==!=)比较2个不同的小时,分​​钟和秒,如果一个大于另一个,则返回布尔值(即h:1) m:5 s:0 vs h:0 m:5 s:0将返回“ true”)。我还没有涉及到第二部分,我将不胜感激,因为我正在尝试逻辑地将整个想法围绕在我的脑海中。

Main.cpp

#include <iostream>
#include "Time.h"

using namespace std;

int main() {

    int hour1, minute1, second1, hour2, minute2, second2;

    cout << "Enter time A (hh, mm, ss): ";
    cin >> hour1;
    cin >> minute1;
    cin >> second1;
    cout <<endl;

    /*cout << "Enter time B(hh, mm, ss): ";
    cin >> hour2;
    cin >> minute2;
    cin >> second;
    cout <<endl;*/

   Time T1(hour1, minute1, second1);

   ++T1;                    //Increases seconds by 1
   T1.displayTime();

   T1++;                    //Increases minutes by 1
   T1.displayTime();

   --T1;                    //Decreases seconds by 1
   T1.displayTime();

   T1--;                    //Decreases minutes by 1
   T1.displayTime();


   return 0;
}

Time.h

#ifndef TIME_H
#define TIME_H

class Time
{
    public:
        Time();
        Time (int h, int m, int s);

        void displayTime();

        Time operator++();
        Time operator++(int);

        Time operator--();
        Time operator--(int);
        /*Time operator>();
        Time operator<();
        Time operator>=();
        Time operator<=();
        Time operator==();
        Time operator!=();*/

    private:
        int hours;
        int minutes;
        int seconds;
};

#endif // TIME_H

Time.cpp

#include <iostream>
#include "Time.h"

using namespace std;

Time::Time(){
    hours = 0;
    minutes = 0;
    seconds = 0;
}

Time::Time(int h, int m, int s){
    hours = h;
    minutes = m;
    seconds = s;
}

void Time::displayTime(){
    cout << "Hours: " << hours <<" Minutes: " << minutes << " Seconds: " <<seconds <<endl;
}

Time Time::operator++(){ //Prefix plus seconds
    ++seconds;
    if (minutes >= 60){
        ++hours;
        minutes -= 60;
    }
    if (seconds >= 60){
        ++minutes;
        seconds -= 60;
    }
    return Time(hours, minutes, seconds);
}

Time Time::operator++(int){ //Postfix plus minutes
    Time T(hours, minutes, seconds);

    ++minutes;
    if(minutes >=60){
        ++hours;
        minutes -= 60;
    }
    if (seconds >= 60){
        ++minutes;
        seconds -= 60;
    }
    return T;
}

Time Time::operator--(){ //PREFIX MINUSS seconds
    --seconds;

    if (seconds == 0){
        --minutes;
        seconds += 59;
    }

    if (minutes == 0){
        --hours;
        minutes += 59;
    }

    return Time(hours, minutes, seconds);
}

Time Time::operator--(int){ //POSTFIX MINUSS minutes
    Time T(hours, minutes, seconds);
    --minutes;

    if (minutes == 0){
        --hours;
        minutes += 59;
    }
    if (seconds == 0){
        --minutes;
        seconds += 59;
    }
    return T;
}


/*Time Time::operator>(){

}

Time Time::operator<(){

}

Time Time::operator>=(){

}

Time Time::operator<=(){

}

Time Time::operator==(){

}

Time Time::operator!=(){

}
*/

如果您发现任何其他错误,请告诉我。

因此,分钟数无法正确减去。似乎它只是从0开始消失,但没有将必要的秒数加回去(如果这样的话)。

谢谢。

1 个答案:

答案 0 :(得分:2)

  

我在-运算符上遇到了麻烦

实际上,您还有很多麻烦! 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))。使用此修复程序,{{1 }}不再正确,您将需要+= 59或最好仅使用+= 60

通常,pre-increment和-decrement运算符返回对当前对象的引用。这将允许e。 G。 = 59

++(++time)

后增加和-减少运算符非常很奇怪...请重新验证是否确实是增加/减少分钟的任务(如果是,我只能甩头而过)你的老师...)。对于任何人来说,这都是一个很大的惊喜,因为操作员的行为与通常的行为完全不同!后者是:

Time& Time::operator++()
{
    // increment as described
    return *this;
}

如果您真的真的会增加分钟数(请注意,具有讽刺意味的是:X增量运算符实际上就像X增量运算符一样,至少在您的初始方法看起来像这样):秒未触及。如果在各个预变量中,则后运算符中所需的就是最外面的 body 。然后可以将它们重新编写为避免代码重复:

Time operator++(int)
{
    Time tmp(*this);
    ++*this;
    return tmp;
}

最后:比较:不幸的是,我们还没有C ++ 20,否则我们可以实现飞船运算符(++seconds; if(seconds == 60) { seconds = 0; *this++; // use post-fix to adjust minutes... } )...没关系,我们仍然可以使用普通函数而是在运算符中使用此符号:

<=>

然后 all 要实现的运算符如下:

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 }}。


奖金::记住溢出但没有单独的标志:

您不再需要其他变量,但它需要更复杂的逻辑。

首先,保留-1(>)将表示发生了环绕。相应地,环绕方法的获取器将>=

在我们以前直接使用operator--的其他地方 ,现在我们将使用getter,它看起来像这样:

return hours == -1;

计算增量值稍微复杂一点:

hours