2010-02-06 18 views
5

Cuando se sobrecarga a los operadores, ¿es necesario sobrecargar> = < = y! =?sobrecarga del operador C++

Parece que sería inteligente para C++ llamar! Operator = for! =,!> Para el operador < = y! < para el operador> =.

¿Es ese el caso, o es necesario sobrecargar todas las funciones?

Respuesta

2

Sí, es necesario, si desea que todos funcionen de la manera que usted quiere que funcionen.

C++ no fuerza ninguna semántica específica en la mayoría de los operadores sobrecargados. Lo único que se soluciona es la sintaxis general para el operador (que incluye ser unario o binario y cosas como precedencia y asociatividad). Esto significa inmediatamente que la funcionalidad real que implementa en su sobrecarga puede ser absolutamente arbitraria. En general, puede que no haya una conexión significativa entre lo que hace el operador == y lo que hace el operador !=. El operador == podría escribir datos en un archivo, mientras que el operador != podría ordenar una matriz.

Si bien la sobrecarga de operadores de una manera tan arbitraria ciertamente no es una buena práctica de programación, el lenguaje C++ no puede asumir nada. Por lo tanto, no, no puede y no usará automáticamente la combinación ! == en lugar de !=, o la combinación ! > en lugar de <=.

+0

Su ejemplo para '==' y '! =' Es bastante artificial. Una más realista sería una clase que representa un objeto SQL, donde tiene que lidiar con la semántica especial de 'NULL'. – dan04

2

No, sólo es necesario sobrecargar el operador == y el operador <, la biblioteca estándar se hará cargo del resto :)

(EDIT: ver using namespace std :: rel_ops;)

+0

No creo que sea así ... Si fuera cierto, ¿por qué esta página daría ejemplo de definir! = En términos de ==? http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html –

+0

Gracias por la aclaración. –

+1

No, no, debe definir explícitamente cada operador. –

0

Hay Son unos pocos shortcuts que puede usar, como CRTP, para obtenerlos automaticallyinjected (vea las diferentes clases de Comparar) en su clase.

+2

Me pregunto por qué esta y la respuesta ahora eliminada de stakx fueron rechazadas. – GManNickG

+0

Me gana, dejé de preocuparme por el representante hace mucho tiempo, pero todavía veo gente jugando juegos que intentan influir en las respuestas. –

+2

Por favor explique los motivos cuando baja la votación. –

7

Boost operators podría ser lo que está buscando. Estos derivarán la mayoría de sus operadores en función de unos pocos fundamentales.

Que C++ no proporciona esto automáticamente tiene sentido, ya que uno podría dar significados totalmente diferentes a < y>, por ejemplo (aunque a menudo sería una mala idea).

+1

C++ proporciona esto como std :: rel_ops, pero es difícil de usar correctamente y posiblemente más corto para que simplemente los escriba en su lugar (evitando la confusión). –

0

Sí! Son cada uno operadores técnicamente diferentes. Los compiladores C++ no son intrínsecamente motores de inferencia, son analizadores/compiladores. Ellos solo harán todo lo que diga que hacer. http://www.parashift.com/c++-faq-lite/operator-overloading.html, http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B

+0

¡Excepto que son motores de inferencia! Mire ADL y descubra las reglas de resolución de sobrecarga de función para un buen dolor de cabeza largo. –

+0

Sospecho que habría muchos investigadores de IA que no estarían de acuerdo con usted en la definición técnica de un motor de inferencia en ciencias de la computación. Pero sí, lo que los compiladores modernos pueden "descifrar" es impresionante. –

+0

La definición que estoy usando: "Un motor de inferencia es una forma de máquina de estados finitos que consta de tres acciones: hacer coincidir, seleccionar y ejecutar reglas". Las reglas son simplemente una combinación de resolución de sobrecarga de función y las declaraciones de funciones y tipos en el programa. No hay argumento de que sea primitivo, por supuesto. –

3

Voy a tomar un punto de vista minoritario aquí. Si ya usas boost, usar operadores de boost no es tan importante. Puede ser la forma correcta y probada de hacer las cosas, pero agregar dependencia de impulso solo para los operadores es una exageración.

Es posible escribir programas complejos C++ sin impulso (que personalmente encuentro estéticamente desagradables) y así mantenerlo simple (estúpida), para responder a la pregunta de OP, si sobrecarga operator ==, también debe sobrecargar operator !=. Lo mismo es cierto para <, >, ++ etc.

+2

Si no te gusta impulsar, por la razón que sea, eso no significa que no puedas usar la misma técnica. Mi respuesta contiene un enlace a un único encabezado independiente que escribí como ejemplo de cómo hacer exactamente eso en este caso. –

+0

Estoy respondiendo la pregunta: C++ no llama automáticamente a 'operator ==' e invierte el resultado cuando '! =' No está definido. Sin disputar que hay una forma automática de hacer eso. –

1

Sí, es necesario sobrecargar los operadores que desee utilizar como los define; C++ no tomará la decisión que describe anteriormente; sin embargo, tenga en cuenta que si la razón por la que está sobrecargando es ordenar su clase, entonces solo necesita anular los operadores utilizados por la rutina de clasificación. En el caso del algoritmo de clasificación RTL, solo necesita anular < y =.

0

Puede usar la sobrecarga para usar nombres definidos por el usuario. Sobrecarga del operador significa usar el mismo operador para realizar operaciones en diferentes artículos que no están en esa categoría. La sobrecarga de funciones significa usar el mismo nombre de función pero diferentes argumentos, para superar la sobrecarga cuando se llama a la misma función durante el bucle.

0

C++ no define, como un lenguaje, a ningún operador en términos de cualquier otro operador sobrecargado. El hecho de que tenga operator+, no significa que obtenga operator+= gratis (a diferencia de Ruby y Scala). El hecho de que tenga el operador < y == no significa que obtenga <= gratis. Solo porque tenga operador == no significa que obtiene != gratis (a diferencia de Ruby y Scala). Solo porque tenga unario operator * (unario) no significa que obtenga operator -> gratis.

std::relops (si se importó correctamente) y proporcionan definiciones predeterminadas, y Boost proporciona algunas mezclas que definen todos los operadores de comparación en términos de < y ==.