web-dev-qa-db-ja.com

クラス内の2つのオブジェクト(呼び出し元オブジェクトとパラメーター)を比較するにはどうすればよいですか?

課題の「日付」クラスを作成していますが、いずれかの関数を実行するのに問題があります。

これは、クラスのヘッダーファイルです。

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)関数です。 2つのDateオブジェクト(呼び出し元オブジェクトとパラメーター)を比較するためにこの関数が必要であり、次を返す必要があります:呼び出し元オブジェクトが時系列で最初に来る場合は-1、オブジェクトが同じ日付である場合は0、パラメーターオブジェクトが時系列で最初に来る場合は1 。

==演算子を使用して単純なifステートメントを実行しようとしましたが、エラーが発生します。

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

オブジェクトが作成されたら、次のように関数を呼び出す必要があります。d1.Compare(d2)

前もって感謝します!

6
n-2r7
_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()のよりスマートな実装があります-他の答えを確認してください。これは非常に簡単で読みやすいですが、仕様に正確に準拠しています。

12

比較関数を実装する方法は次のとおりですが、形式に慣れるまで少し時間がかかります。

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

Compareではoperator==を使用しませんが、operator==の実装方法を説明する回答も必要な場合は問題ありません。その理由は、operator==がcompareと同じフィールドを確認する必要があることは明らかであり、falseが返された場合、Compareは非常に類似した作業を再度実行するためです。効率はおそらく問題ではありませんが、ロジックが重複しています。

そして、その価値については、慣用的なC++は、オールインワンの比較関数ではなく、operator<を実装し、場合によっては一貫したoperator==operator>も実装することです。演算子は、標準のアルゴリズムが検索と並べ替えに使用するものであり、その他はすべて続きます。 Javaは別の方法で物事を行うことを選択しました。

8
Steve Jessop

クラスのpublicエリアに

bool operator==(const Date& rhs) const {
    return
       year == rhs.year
       && month == rhs.month
       && day == rhs.day
    ;
}
5
Notinlist

オブジェクトの比較内容による、つまり、あなたの場合、日付は日、月、年が等しい(そしておそらくformat-セマンティクスによっては)。

また、C++には、オブジェクト比較のための優れた機能がすでに含まれています。operator ==は、Compareメソッドを呼び出すよりも明確なコードを記述できます。

ちなみに、これには注意してください:

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

条件が真の場合、cout行が実行されます。条件が偽の場合でも、returnが実行されます。

4
Eli Bendersky

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
Greg Bacon

ユーザー定義型にoperator ==を使用するには、それを実装する必要があります。さらに、Compare関数はconstメンバー関数としてマークする必要があります。

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

bool operator==(const Date& rhs) const
{
    return 0 == Compare(rhs);
}
3
John Dibling

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();
      }
   }
}
0
Vivin Paliath