【问题标题】:Creating a method that compares two objects创建一个比较两个对象的方法
【发布时间】:2013-12-10 23:10:27
【问题描述】:

编辑!!

我正在自学 C++,只是学习课程。为了练习,我用一些方法创建了一个Date 类。我目前正在尝试练习这个问题:

使用Date 类创建一个比较两个 Date 对象并返回两者中较大者的方法。

所以我已经有了一些我在下面制作的代码和方法。这是我感到困惑的地方:当您调用一个方法时,它的形式为:<object>.<method>。假设我有两个日期对象date1date2。我不明白如何创建一个采用两个日期对象的日期方法,因为该方法已经作用于其中一个对象。换句话说,我本来希望有这样的东西:date1.compareDate(date2),并且这个方法会返回具有更大价值的对象。有人可以解释一下我是如何解决这个问题的吗?

我尝试在我的方法中执行此操作:compareDate()。我创建了另一种方法 convert ,它创建了一个 YYYYMMDD 形式的整数,我可以使用简单的布尔逻辑来比较更大的值。

请注意,我想返回较大的 Date 对象,而不是布尔值。

提前谢谢你。

#include <iostream>
#include <iomanip>
using namespace std;

// Class declaration statement
class Date
{
    private:
        int month;
        int day;
        int year;
    public:

        Date(int = 7, int = 4, int = 2012); // Constructor
        void setDate(int, int, int);        // Member to copy a date
        void showDate();                    // Member method to display date
        int convert();
        bool leapYear();
        string dayOfWeek();
        void nextDay();
        void priorDay();
        Date compareDate(Date, Date);
};

// Class Implementation section
Date::Date(int mm, int dd, int yyyy)
{
    month = mm;
    day = dd;
    year = yyyy;
}

void Date::setDate(int mm, int dd, int yyyy)
{
    month = mm;
    day = dd;
    year = yyyy;
}

void Date::showDate()
{
    cout << "The date is ";
    cout << setfill('0')
         << setw(2) << month << '/'
         << setw(2) << day << '/'
         << setw(2) << year % 100;
    cout << endl;
}

int Date::convert()
{
    // Convert date to the integer format:  YYYYMMDD
    return year*10000 + month*100 + day;
}

bool Date::leapYear()
{
    if( (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) )
        return true;
    else
        return false;
}

string Date::dayOfWeek()
{
    int dayInt;
    int mm, yyyy, dd, YYYY;
    int century, T, dayOfWeek;


    yyyy = year;
    mm = month;
    dd = day;

    if( mm < 3 )
    {
        mm = mm + 12;
        yyyy = yyyy - 1;
    }        

    century = int( yyyy/100 );
    YYYY = yyyy%100;

    T = dd + int( 26 * (mm + 1)/10) + YYYY + int(YYYY/4) + int( century/4)
        -2*century;

    dayOfWeek = T % 7;

    if( dayOfWeek < 0 )
        dayOfWeek += 7;

    if( dayOfWeek == 0 )
        return "Saturday";
    else if( dayOfWeek == 1)
        return "Sunday";
    else if( dayOfWeek == 2)
        return "Monday";
    else if( dayOfWeek == 3)
        return "Tuesday";
    else if( dayOfWeek == 4)
        return "Wednesday";
    else if( dayOfWeek == 5)
        return "Thursday";
    else if( dayOfWeek == 6)
        return "Friday";
    else
    {
        cout << "dayOfWeek = " << dayOfWeek << endl;
        return "Bad dayOfWeek Calc";
    }
}

void Date::nextDay()
{
    // Increment month and day if at 31 days in month
    // Skip December because have to increment year too
    if( (month == 1 || month == 3  || month == 5 || month == 7 || 
         month == 8 || month == 10) && day == 31 )
    {
        month++;
        day = 1;
    }
    // Increment month and day if at 30 days in month
    else if( (month == 4 || month == 6  || month == 9 || month == 11)
                && day == 30)
    {
        month++;
        day = 1;
    }
    // New year
    else if( month == 12 && day == 31 )
    {
        month = 1;
        day = 1;
        year++;
    }
    // Leap year
    else if( leapYear() && month == 2 && day == 29 )
    {
        month = 3;
        day = 1;
    }
    // Not leap year
    else if( !leapYear() && month == 2 && day == 28)
    {
        month = 3;
        day = 1;
    }
    // Regular day
    else
        day++;
}

void Date::priorDay()
{
    // Increment month and day if at 31 days in month
    // Skip December because have to increment year too
    if( (month == 5 || month == 7 || 
         month == 8 || month == 10 || month == 12) && day == 1 )
    {
        month--;
        day = 30;
    }
    // Increment month and day if at 30 days in month
    else if( (month == 2 || month == 4 || month == 6  || month == 9 || month == 11)
                && day == 1)
    {
        month--;
        day = 31;
    }
    // beginning year
    else if( month == 1 && day == 1 )
    {
        month = 12;
        day = 31;
        year--;
    }
    // Leap year
    else if( leapYear() && month == 3 && day == 1 )
    {
        month--;
        day = 29;
    }
    // Not leap year
    else if( !leapYear() && month == 3 && day == 1)
    {
        month--;
        day = 28;
    }
    // Regular day
    else
        day--;

}

Date Date::compareDate(Date date1, Date date2)
{
   // Return the greater date
    if( date1.convert() > date2.convert() )
        return date1;
    else
        return date2;
}


int main()
{
    Date c(4,1,2000);
    Date d(11, 1, 2013);
    b.setDate(12,25,2009);    

    cout << Date.compareDate(c,d) << endl;

    return 0;
}

【问题讨论】:

  • 您可以直接比较,而不是您的创意convert 方法。但你的代码很好。

标签: c++ class object methods


【解决方案1】:

您可以使用运算符比较您的 Date 对象(您应该自己编写)

friend bool operator> (const Date& D1, const Date& D2)
{
  return D1.convert() > D2.convert();
}

当且仅当 D1 > D2 时,该运算符应该返回 true。如果此运算符需要访问 Date 对象的私有部分,则必须在 Date 类中将其声明为 friend

【讨论】:

  • 那么,一旦我将该运算符包含到我的课程中,我是否只需将这一行从:if( date1.convert() &gt; date2.convert() ) 更改为if( date1 &lt; date2 )?那我怎么调用compareDate方法呢?
  • 不完全是。如果您将此运算符包含到您的类中,那么您将能够在代码中的任何地方使用像date1 &gt; date2 这样的表达式。如果您需要相反的不等式,您将需要另一个 operator&lt; - 并且可以使用许多其他运算符:==、!=、= 等。顺便说一句,如果您将此运算符包含在类中,您也将是能够将您的 convert 方法设为私有。
  • 而且 - 从两个对象返回最大值的常用 C++ 习语是:inline Date max(const Date&amp; d1, const Date&amp; d2) {return (d1 &lt; d2) ? d2 : d1;}
【解决方案2】:

首先,将所有不会改变你的类的函数设为常量:

int convert() const;

将以下运算符添加到您的类中:

bool operator< (const Date &other) const
{
    return convert() < other.convert();
}

Alexey 的代码也可以,但我更喜欢这个有两个原因:第一,不应该在可以添加成员函数的时候引入友元函数,第二,如果你要去的话,operator 更重要使用 stl 容器或算法。 stl::set, stl::map, stl::sort 都使用 operator<.>

【讨论】:

  • 好的,非常感谢。但是我的compareDate 方法该怎么办?我需要对此进行任何更改吗?我该怎么称呼它?
  • 那么,一旦我将该运算符包含到我的课程中,我是否只需将此行从:if( date1.convert() &gt; date2.convert() ) 更改为if( date1 &lt; date2 )?那我怎么调用compareDate方法呢?
  • compareDate 方法对比较没有意义:它返回 Date 而不是表示哪个输入日期更大的整数。如果 compareDate 中的 code 是您的意图,那么您应该将其重命名为 maxDate,因为它确实返回两​​个输入的最大值,而不是指示哪个更大。另一方面,如果您的意图是比较您应该使用 的日期
【解决方案3】:

您可以创建一个(独立的)函数,该函数需要两个 Dates,如前所述。

您还可以创建一个 Date 方法,该方法忽略 this,获取并比较两个日期,然后返回其中一个。这就是你所做的。但是您仍然必须通过实例调用此方法。还弥补了&lt;&lt; 过载的不足:

c.compareDate(c,d).showDate();

有效。但当然这是不好的做法,因为您要的是不需要的实例 (c.)。

你想做什么,

Date.compareDate(c,d)

表明您正在寻找静态方法。您需要这样声明它们:

class Date {
    ...
    static Date compareDate(Date, Date);
};

然后这样称呼他们:

Date::compareDate(c,d).showDate();

(您也可以有一个方法Date compareDate(Date),将this 与参数进行比较,但这也很糟糕。)

--

您应该为 compareDate 选择一个更好的名称,因为目前尚不清楚它是否会返回一个全新的 Date 对象。

请注意,这里所有以前的答案(以及我的第一个版本)都错误地认为您想返回 bool。这是因为这就是应该进行比较的方式,最好使用 operator&lt; 重载。

【讨论】:

    猜你喜欢
    • 2019-07-19
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    相关资源
    最近更新 更多