2010-02-03 22 views
5

Piszę klasy „Data” do przypisania i mam problemy wykonując jedną z funkcji.Jak porównać dwa obiekty (obiekt wywołujący i parametrów) w klasie?

Jest to plik nagłówka dla klasy.

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

Funkcja członkiem Próbuję zrobić to int Porównaj (const Data & d) funkcja. Potrzebuję tej funkcji do porównywania dwóch obiektów Date (wywołujący przedmiotu oraz parametr ) i powinien wrócić: -1 jeśli obiekt wywołanie przychodzi pierwszy chronologicznie 0 jeśli obiekty są tego samego dnia, a 1 jeśli obiekt parametr przychodzi pierwszy chronologicznie.

Próbowałem zrobić prosty if z operatorem == ale pojawiają się błędy.

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

Po obiekty są tworzone, funkcja powinna nazywać się ten d1.Compare (d2)

Z góry dziękuję!

Odpowiedz

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

Zazwyczaj you'lll też chcą zapewnić przeciążone operatory porównania, na przykład (również w ramach definicji klasy):

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

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

... // consider using boost::operators 

PS: Są inteligentniejsze implementacje Compare() - wystarczy sprawdzić drugi odpowiedzi. Ten jest dość prosty i czytelny, ale jest zgodny z twoją specyfikacją.

+0

Dziękuję, właśnie to próbowałem zrobić. –

5

do public obszarze klasy za

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

Należy zauważyć, że metoda jest stała. Twoja metoda Compare() (i inne) powinna być także const. Jeśli twój Porównaj() byłby stały, mógłbym go nazwać od operatora ==() :-) – Notinlist

4

Porównaj obiekt o treści, czyli w przypadku terminów są równe z dnia, miesiąca i roku są równe (a może format - w zależności od semantyki) .

Również C++ zawiera już doskonałe narzędzie do porównywania obiektów: operator ==, które umożliwia pisanie bardziej przejrzystego kodu niż wywoływanie metody Compare.

Nawiasem mówiąc, dbać o to:

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

Jeśli warunek jest spełniony, linia cout zostanie wykonany. return zostanie wykonane, nawet jeśli warunek jest fałszywy.

+1

+1, ładny połów na zwrotnym oświadczeniu. – Void

0

Nie można zrobić d1 === d2, ponieważ wierzę, że porównuje adresy pamięci (nie uczyniły C++ na chwilę).

Należy napisać funkcję, która porówna każdego członka klasy Date i zwróci liczbę ujemną, 0 lub liczbę dodatnią. Ujemny oznacza mniejszy, 0 oznacza taki sam, a dodatni oznacza większy.

Na przykład w Javie:

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(); 
     } 
    } 
} 
+2

d1 == d2 nie kompiluje się, chyba że operacja jest zaimplementowana w dowolnym miejscu. W tym przypadku nie jest zaimplementowany. –

+0

PO jednoznacznie stwierdza "... funkcję należy nazwać tak, jak to d1.Compare (d2)", co oznacza, że ​​ani d1, ani d2 nie są adresami pamięci (wskaźnikami). Porównanie adresów pamięci w tym przypadku pociągałoby za sobą coś w rodzaju "& d1 == & d2", a nie "d1 == d2". Utworzenie operatora równości, takiego jak ten opublikowany na stronie @Notinlist, zapewnia pożądaną semantykę d1 == d2. – Void

+0

Dziękuję za "ten" wskaźnik, nie myślałem o tym. –

1

Aby korzystać == operatora dla typów zdefiniowanych przez użytkownika, należy je wdrożyć.Ponadto Twój Porównaj funkcja powinna być oznaczona jako const funkcji członka:

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

bool operator==(const Date& rhs) const 
{ 
    return 0 == Compare(rhs); 
} 
4

semantyka C++ 's || uczynić to trochę bałagan:

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

Dziękuję, to też pomogło. –

+0

@jualin Nie ma za co! –

+0

Ale jeśli naprawdę musisz uruchomić nazwę z podkreśleniem, upewnij się, że nie znajduje się w globalnej przestrzeni nazw - to niedozwolone. –

7

Oto jak mogę realizować swoje Porównaj funkcji, chociaż format trwa chwilę, aby przyzwyczaić się do:

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

Albo:

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

Nie użyłbym operator== w porównania, chociaż odpowiedzi z informacją, jak wdrożyć operator== są w porządku, jeśli chcesz, że dobrze. Powodem jest to, że operator== wyraźnie będzie musiał patrzeć na te same pola, co porównanie, a jeśli zwróci wartość false, to porównanie ponownie wykona bardzo podobną pracę. Wydajność prawdopodobnie nie jest problemem, ale powtarza logikę.

I za to, co jest tego warte, idiomatic C++ ma zaimplementować operator< i być może również spójny operator== i operator>, zamiast funkcji porównania w jednym urządzeniu. Operatory są tym, czego używają standardowe algorytmy do wyszukiwania i sortowania, a wszystko inne następuje. Java postanowiła robić różne rzeczy.

+0

+1. Niesamowita odpowiedź. – ChadNC

+0

Dziękuję, to świetne wyjaśnienie. –