2010-02-03 15 views
5

Estoy escribiendo una clase de "Fecha" para una tarea y estoy teniendo problemas para realizar una de las funciones.¿Cómo se comparan dos objetos (el objeto que llama y el parámetro) en una clase?

Este es el archivo de encabezado de la clase.

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

La función miembro que estoy tratando de hacer es el int Comparar (const Fecha & d) función. Necesito esta función para comparar dos objetos Date (el objeto que llama y el parámetro ), y debería devolver: -1 si el objeto llamante es el primero cronológicamente, 0 si los objetos son de la misma fecha y 1 si el objeto parámetro viene primero cronológicamente

He intentado hacer una instrucción if simple con el operador == pero obtengo errores.

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

Una vez creados los objetos, la función debe ser llamada como esto d1.Compare (d2)

gracias de antemano!

Respuesta

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

Por lo general, you'lll también quieren proporcionar a los operadores de comparación sobrecargados, por ejemplo (también dentro de la definición de clase):

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

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

... // consider using boost::operators 

PS: Hay implementaciones más inteligentes de Compare() - simplemente marque la otra respuestas Este es bastante sencillo y legible, pero se ajusta exactamente a su especificación.

+0

Gracias, eso es exactamente lo que estaba tratando de hacer. –

5

en el área de la clase public

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

Observe que el método es const. Su método Compare() (y otros) también deberían ser const. Si su Compare() sería const, podría llamarlo desde el operador ==() :-) – Notinlist

4

Compare objeto por contenidos, es decir, en su caso, las fechas son iguales del día, mes y año son iguales (y tal vez format - dependiendo de su semántica) .

Además, C++ incluye ya una gran facilidad para la comparación de objetos: operator == que permite escribir código más claro que llamar a un método Compare.

Por cierto, tenga cuidado con esto:

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

Si la condición es verdadera, se ejecutará la línea cout. El return se ejecutará incluso si la condición es falsa.

+1

+1, atrapando la declaración. – Void

0

No puede hacer d1 === d2, porque creo que compara las direcciones de memoria (hace tiempo que no hace C++).

Lo que necesita hacer es escribir una función que compare cada miembro de su clase Date y devuelva un número negativo, 0 o un número positivo. Negativo significa menos, 0 significa lo mismo y positivo significa mayor.

Por ejemplo, en 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(); 
     } 
    } 
} 
+2

d1 == d2 no se compila a menos que la operación se implemente en algún lugar. En este caso, no está implementado. –

+0

El OP declara explícitamente "... la función debe llamarse así d1.Compare (d2)", lo que significa que ni d1 ni d2 son direcciones de memoria (punteros). La comparación de las direcciones de memoria en este caso implicaría algo como "& d1 == & d2", no "d1 == d2". La creación de un operador de igualdad como el @Notinlist publicado proporciona la semántica d1 == d2 deseada. – Void

+0

Gracias por el puntero "this", no pensé en eso. –

1

Para utilizar el operador == para los tipos definidos por el usuario, debe ponerla en práctica.Además, su función de comparación debe ser marcado como un método constante:

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

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

La semántica de || marca C++ 's esto un poco desordenados:

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

Gracias, eso también ayudó. –

+0

@jualin ¡De nada! –

+0

Pero si realmente debe comenzar el nombre con un guión bajo, asegúrese de que no esté en el espacio de nombre global; eso no está permitido. –

7

de cómo podría implementar su función Compare aquí, aunque el formato se toma un momento para acostumbrarse a:

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

O quizás:

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

No utilizaría operator== en Comparar, aunque las respuestas que le dicen cómo implementar operator== también están bien si quiere eso. La razón es que operator== claramente tendrá que mirar los mismos campos compare does, y si devuelve false entonces Compare hará un trabajo muy similar de nuevo. La eficiencia probablemente no sea un problema, pero duplica la lógica.

Y por si sirve de algo, C++ idiomática es implementar operator< y posiblemente también una función constante y operator==operator>, en lugar de un todo-en-uno de comparación. Los operadores son lo que utilizan los algoritmos estándar para buscar y clasificar, y todo lo demás sigue. Java eligió hacer las cosas de manera diferente.

+0

+1. Impresionante respuesta. – ChadNC

+0

Gracias, esa es una gran explicación. –

Cuestiones relacionadas