2012-06-10 8 views
10

Mientras yo entiendo por qué no hay operator== para shared_ptr y unique_ptr, me pregunto por qué no hay ninguno de shared_ptr y weak_ptr. Especialmente dado que puede crear un weak_ptr a través de una referencia en shared_ptr. Supongo que durante el 99% del tiempo desea lhs.get() == rhs.get(). Ahora avanzaría y lo introduciría en mi código a menos que alguien me diga una buena razón, por qué uno no debería hacer tal cosa.igualdad perdido entre shared_ptr y weak_ptr

+3

Pero 'weak_ptr' no tiene un método' get'. –

+0

Derp. Leer mal la pregunta –

Respuesta

15

weak_ptr doesn 'tiene un método get() porque debe bloquear explícitamente el weak_ptr antes de poder acceder al puntero subyacente. Hacer esto explícito es una decisión de diseño deliberada. Si la conversión fuera implícita, sería muy fácil escribir un código que no sería seguro si se destruyera el último shared_ptr del objeto, mientras que el puntero subyacente obtenido del weak_ptr todavía estaba siendo examinado.

This boost page tiene una buena descripción de las trampas y por qué weak_ptr tiene una interfaz tan limitada.

Si necesita hacer una comparación rápida, puede hacer shared == weak.lock(). Si la comparación es verdadera, entonces usted sabe que weak debe seguir siendo válida ya que tiene un shared_ptr por separado para el mismo objeto. No hay tal garantía si la comparación devuelve falso.

+0

Llamar 'lock' para una parte más grande del código realmente tiene más sentido. Buena decisión de diseño. – abergmeier

4

Porque tiene un costo.

A weak_ptr es como un observador, no un puntero real. Para hacer cualquier trabajo con él, primero debe obtener un shared_ptr usando su método lock().

Esto tiene el efecto de adquirir la propiedad, pero es tan costoso como copiar un shared_ptr normal (incremento de cuenta, etc.) por lo que no es nada trivial.

Como tal, al no proporcionar ==, se ve obligado a dar un paso atrás y realmente comprobar si realmente lo necesita o no.

+2

No estoy seguro de que comparar las necesidades de igualdad con la validez, y como tal podría implementarse de forma económica: o bien 'weak_ptr' se refiere a la misma entidad, en cuyo caso debe ser válida (o 0), o se refiere a otra entidad, en cuyo caso no nos importa si es válida. –

+0

@KonradRudolph: tal vez, tal vez no. Pero debido a que la obtención del puntero sería inseguro en general (ya que tendría el puntero pero no podría acceder al puntero), no puede obtener el puntero de 'weak_ptr' y se ve obligado a pasar por' shared_ptr'. Entonces ... –

+1

No, obtener el puntero es seguro, siempre que se haga * internamente *. –

Cuestiones relacionadas