2011-11-04 13 views
13

Por ejemplo: en un archivo de cabecera C++, si he definido un struct Record y me gustaría utilizarlo para una posible clasificación de modo que yo quiero sobrecargar el less operator. Aquí hay tres formas que noté en varios códigos. Me di cuenta de que más o menos: si voy a poner en un Recordstd::set, map, priority_queue, ... Contenedores, la versión 2 obras (probablemente la versión 3 también); si voy a guardar Record en un vector<Record> v y luego llamar al make_heap(v.begin(), v.end()) etc., entonces solo funciona la versión 1.C++ menos sobrecarga del operador, ¿qué manera de usar?

struct Record 
    { 
     char c; 
     int num; 

     //version 1 
     bool operator <(const Record& rhs) 
     { 
     return this->num>rhs.num; 
     } 

     //version 2 
     friend bool operator <(const Record& lhs, const Record& rhs) //friend claim has to be here 
     { 
     return lhs->num>rhs->num; 
     } 
    }; 

en el mismo archivo de cabecera por ejemplo:

 //version 3 
     inline bool operator <(const Record& lhs, const Record& rhs) 
     { 
     return lhs->num>rhs->num; 
     } 

Básicamente, me gustaría lanzar las preguntas para ver si alguien podría llegar a algún resumen de lo que es la diferencia entre estos tres métodos y ¿Cuáles son los lugares correctos para cada versión?

+3

mejorar su calificación aceptar. –

+0

podría publicar programas de ejemplo completos para cada caso que no funciona –

+2

No veo ninguna versión3 –

Respuesta

5

Ellos son esencialmente los mismos, que no sea el primero de los cuales no constante y que le permite modificar en sí.

prefiero la segunda por 2 razones:

  1. No tiene que ser un friend.
  2. lhs no tiene que ser un Record
+0

Creo que la segunda versión, si reclama el operador user268451

+0

@ user268451 No tiene que ser un amigo. En realidad, es mejor si * no es * uno, ya que conduce a una mejor encapsulación. – Pubby

+0

@ Pubby8 Si quiere definir una función gratuita desde dentro de una clase, tendrá que agregar 'amigo'. Esto no tiene nada que ver con acceder a los miembros privados. – Sjoerd

-4

Favor en clase a menos que no pueda ser en la clase porque el primer argumento es del tipo incorrecto.

+2

. En realidad, siempre se debe favorecer fuera de la clase, de modo que se apliquen las conversiones en los tipos izquierdo y derecho (y no solo en el correcto). Si es posible hacerlo no amigo, aún mejor, ya que desacopla al operador de la clase que lo implementa solo en términos de la interfaz pública. –

+2

¡No desea conversiones en operadores de comparación a menos que sea una especie de número! – Joshua

+1

@Joshua eso no siempre es cierto, si algún contenedor (mapa, conjunto ordenado, ...) lo necesita, puede implementarlo para clases "sin número". – Kashyap

5

La mejor manera de definir el operador es menos:

struct Record{ 
    (...) 
    const bool operator < (const Record &r) const{ 
     return (num < r.num); 
    } 
}; 
+2

Esto no permite las conversiones en el lado izquierdo, por lo que definitivamente no es la * mejor manera *. – Sjoerd

+2

La ruta de las conversiones ipmlicit es peligrosa y no debe caminar – g24l