c++ - 运算符重载逻辑问题

标签 c++ oop operator-overloading overloading

我们在类里面的一项作业是创建一个程序,该程序使用对象来显示小时、分钟和秒。有了这些数字,我们现在必须重载各种运算符,这些运算符会将秒/分钟增加 1,并使用++ 和 -- 减少它们。我在使用 -- 运算符时遇到了一些麻烦,因为它没有按预期工作,如果我输入 0 分钟,它会减少返回值的分钟数,例如 128 分钟。当我开始从事这项工作时,我非常感谢您的帮助。

然后第二部分是使用其他运算符 (> < >= <= == !=) 比较 2 个不同的小时、分钟和秒,如果一个大于另一个则返回一个 bool 值(即 h:1 m:5 s:0 与 h:0 m:5 s:0 将返回“真”)。我还没有进入第二部分,希望能得到一些关于如何开始的指示,因为我试图从逻辑上围绕整个想法。

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

时间.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

时间.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 中减去,但没有向它添加必要的秒数(如果这有意义的话)。

谢谢。

最佳答案

Im having some trouble with the -- operator

其实,你的麻烦还不少!已经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 是有效时间!因此,您需要在递减(if(seconds-- == 0))之后检查 0 或之后检查负值(--seconds; if(seconds == -1)if (seconds < 0))。通过此修复,+= 59 将不再正确更多,您需要 += 60 或最好只需要 = 59

通常,预递增和递减运算符返回对当前对象的引用。这将允许 e。 G。 ++(++time) :

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

后递增和递减运算符非常奇怪...请重新验证是否真的需要递增/递减分钟数(如果是这样,我只能摇头你的老师...)。这对任何人来说都是一个巨大的惊喜,因为运算符(operator)的行为与通常的行为完全不同!后者是:

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

如果你真的,真的应该增加分钟数(注意讽刺:post-X-crement 运算符实际上表现得像 pre-X-crement,至少你的初始方法看起来像这样):离开秒不动。然后,您在后运算符中所需要的只是相应预变体中最外层 if 的 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-- ) 表示发生了回绕。相应地,环绕的 setter/getter 将是 return hours == -1; .

在我们之前使用过的任何地方hours直接,我们现在使用 getter for,它看起来像这样:

int Time::getHours() const
{
    return hours + (hours == -1);
}

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

hours = (getHours() + 1) % 24 - (hours == 23);

关于c++ - 运算符重载逻辑问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55705459/

相关文章:

java - 如何获取我的对象的父对象的实例

c++ - 我怎样才能 "double overload"一个运算符(operator)?

c# - 这是避免不断创建对象的好习惯吗?

c++ - 运算符重载实现 : 0xC0000005: Access violation reading location

c++ - 错误 C2664 : 'bool Strless::operator ()(const TCHAR *&,const TCHAR *&) const' : cannot convert parameter 1 from 'wchar_t *const ' to 'const TCHAR *&'

c++ - 为什么在初始化私有(private)静态成员时允许调用私有(private)静态方法?

javascript - 从构造上的参数设置任意对象属性

java - Java 中的基类实例和派生类实例之间的物理内存是如何组织的?

c++ - 1000.f 中的 .f 是什么意思? C++

c++ - 为什么 C++ 需要对 malloc() 进行强制转换,而 C 不需要?