Как сравнить два объекта (вызывающий объект и параметр) в классе? - PullRequest
6 голосов
/ 03 февраля 2010

Я пишу класс «Дата» для задания, и у меня возникают проблемы с выполнением одной из функций.

Это заголовочный файл для класса.

class Date
{
public:
Date();                                  // Constructor without parameters
Date(int m, int d, int y); // Constructor with parameters.

// accessors
int GetMonth();               // returns the size of the diamond
int GetDay();
int GetYear();

// mutators
bool Set(int m, int d, int y);
bool SetFormat(char f);

// standard input and output routines
void Input();             
void Show();              
void Increment(int numDays = 1);                 
int Compare(const Date& d);     

private:
int month,                    // month variables
    day,                 // day variable
    year;               // year variable
char format;
};

Функция-член, которую я пытаюсь создать, это функция int Compare (const Date & d). Мне нужна эта функция для сравнения двух объектов Date (вызывающий объект и параметр), и должен возвращать: -1, если вызывающий объект находится первым в хронологическом порядке: 0, если объекты имеют одинаковую дату, и 1, если объект параметра на первом месте в хронологическом порядке.

Я пытался сделать простое выражение if с оператором ==, но получаю ошибки.

  if (d1 == d2)
     cout << "The dates are the same";
     return (0);

После создания объектов функцию следует вызывать следующим образом: d1.Compare (d2)

Заранее спасибо!

Ответы [ 7 ]

12 голосов
/ 03 февраля 2010
int Date :: Compare (const Date& d) {

   if (year<d.year) {
      return -1;
   }
   else if (year>d.year) {
      return 1;
   }
   else if (month<d.month) {
      return -1;
   }
   else if (month>d.month) {
      return 1;
   }
   // same for day

   return 0;
}

Как правило, вы также захотите предоставить перегруженные операторы сравнения, например (также в рамках определения класса):

bool operator == (const Date& d) const {
   return !Compare(d);
}

bool operator < (const Date& d) const {
  return Compare(d)<0;   
}

... // consider using boost::operators

PS: есть более разумные реализации Compare() - простопроверьте другие ответы.Этот довольно простой и читаемый, но в точности соответствует вашей спецификации.

8 голосов
/ 03 февраля 2010

Вот как я могу реализовать вашу функцию сравнения, хотя для привыкания к формату требуется время:

int Date::Compare(const Date& d) const {
  return
    (year < d.year)   ? -1 :
    (year > d.year)   ?  1 :
    (month < d.month) ? -1 :
    (month > d.month) ?  1 :
    (day < d.day)     ? -1 :
    (day > d.day)     ?  1 :
                         0;
}

Или, возможно:

template<typename T>
int Compare(T a, T b) {
    if (a < b) return -1;
    if (b < a) return 1;
    return 0;
}

int Date::Compare(const Date& d) const {
    int a = Compare(year, d.year);
    if (a == 0) a = Compare(month, d.month);
    if (a == 0) a = Compare(day, d.day);
    return a;
}

Я бы не стал использовать operator== в Сравнении, хотя ответы, говорящие вам, как реализовать operator==, хороши, если вы тоже этого хотите. Причина в том, что operator== явно придется посмотреть на те же поля, что и для сравнения, и если он вернет false, тогда Compare снова выполнит очень похожую работу. Эффективность, вероятно, не проблема, но она дублирует логику.

И что стоит, идиоматический C ++ должен реализовать operator< и, возможно, также согласованные operator== и operator>, а не функцию сравнения "все в одном". Операторы - это то, что стандартные алгоритмы используют для поиска и сортировки, а все остальное следует. Ява решила действовать по-другому.

5 голосов
/ 03 февраля 2010

в класс public область

bool operator==(const Date& rhs) const {
    return
       year == rhs.year
       && month == rhs.month
       && day == rhs.day
    ;
}
4 голосов
/ 03 февраля 2010

Семантика C ++ || делает это немного загроможденным:

static inline int cmp(int a, int b)
{
  return a < b ? -1 : a == b ? 0 : 1;
}

int Date::Compare(const Date& d)
{
  int result;
  (result = cmp(year, d.year))     ||
    (result = cmp(month, d.month)) ||
      (result = cmp(day, d.day));

  return result;
}
4 голосов
/ 03 февраля 2010

Сравните объект по содержанию , т.е. в вашем случае даты равны дням, месяцам и годам равны (и, возможно, format - в зависимости от вашей семантики).

Кроме того, в C ++ уже есть отличное средство для сравнения объектов: operator ==, которое позволяет писать более понятный код, чем вызов метода Compare.

Кстати, позаботьтесь об этом:

  if (d1 == d2)
     cout << "The dates are the same";
     return (0);

Если условие истинно, будет выполнена строка cout.return будет выполнено, даже если условие ложно.

3 голосов
/ 03 февраля 2010

Чтобы использовать оператор == для пользовательских типов, вы должны реализовать его.Кроме того, ваша функция сравнения должна быть помечена как постоянная функция-член:

class Date
{
...
int Compare(const Date& d) const;     

bool operator==(const Date& rhs) const
{
    return 0 == Compare(rhs);
}
0 голосов
/ 03 февраля 2010

Вы не можете сделать d1 === d2, потому что я считаю, что он сравнивает адреса памяти (давно не делал C ++).

Что вам нужно сделать, это написать функцию, которая будет сравнивать каждого члена вашего класса Date и возвращать отрицательное число, 0 или положительное число. Отрицательное означает меньшее, 0 означает то же самое, а положительное означает большее.

Например, в Java:

public int compareTo(Date date) {
  int returnValue = 0;

   returnValue = this.getYear() - date.getYear();

   if(returnValue == 0) {
      returnValue = this.getMonth() - date.getMonth();

      if(returnValue == 0) {
         returnValue = this.getDay() - date.getDay();
      }
   }
}
...