2012-03-15 9 views

Respuesta

0

Sí. shared_ptr solo te da el beneficio de saber cuándo liberar su memoria asignada contando referencias a ella. Debería verificar si es válido antes de usarlo, suponiendo que no tenga otra forma de saber de antemano que definitivamente no será nulo, pero eso está al lado de si está usando un shared_ptr o no.

+2

Si bien este es un buen consejo general, se debe tener en cuenta que, al igual que otros punteros, si el puntero no puede ser nulo debido a algún programa/clase invariante, entonces no es necesario verificarlo. Por ejemplo, si el puntero compartido de un miembro privado se establece y verifica en el constructor y luego nunca se vuelve a asignar, no es necesario verificarlo en cada llamada a la función miembro. –

+0

André tiene razón. – Almo

+0

@ André: O debería verificarse en un 'assert'. – ildjarn

5

No. Si está en el contrato de la función que debe ser válida, entonces la forma más rápida de llamar la atención sobre el hecho de que la persona que llama tiene un error es bloquearse. Fallar tan pronto como puedas.

+0

El problema con esto es que técnicamente solo causará UB; no hay garantía de un error _observable_, muchlessless crash. – ildjarn

+2

@ildjarn: "Fallo tan pronto como puedas" - 'assert'. :) – Xeo

+0

+1 porque es exactamente lo que hago. Cosas inteligentes típicas que no escucharás en cursos de programación universitarios dirigidos por profesores incompetentes y no programadores. – ceztko

3

Depende de si es realmente una posibilidad durante la ejecución normal del programa que el shared_ptr sea nulo. De lo contrario, aplique la responsabilidad como una condición previa para el usuario de f y quizás assert(ptr);. Tenga en cuenta que no solo se aplica al shared_ptr, sino que el uso de cualquier puntero realmente. Aunque quizás deberías usar referencias aquí.

+0

Específicamente no enumero la pregunta proporcionando una función con el parámetro de referencia b/c. Suponemos que la referencia no debe apuntar a un puntero vacío y no siempre necesitamos verificar una referencia. Sin embargo, todavía puede hacerlo no válido de alguna manera. – q0987

2

depende de su escenario:

Si el f() es una función de función pública/API donde se tiene ningún control sobre lo que alguien puede pasar que entonces sí que debe comprobar.

Si la función es una función de miembro privado o está documentada como que requiere un puntero válido, entonces usaría assert. Tiene la necesidad de no tener gastos fijos en versiones de lanzamiento y muestra rápidamente el problema en las compilaciones de depuración.

void f(shared_ptr<T> ptr) 
{ 
    assert(ptr && "ptr is null!"); 

    ..... 
} 
+1

No me gusta para validar los valores de tiempo de ejecución a medida que obtiene un comportamiento diferente en depuración y liberación. Assert debe reservarse para invariantes de aplicación, no para verificaciones de tiempo de ejecución. –

0

Digamos que: si su void foo(shared_ptr<int> ptr) es una biblioteca de propósito general y que desea informar al usuario en tiempo de ejecución que el valor nullptr es incompatible (una excepción) o se trata con un código base diferente sí, es correcto para verificarlo Si no necesita almacenar el shared_ptr en algún lugar con su foo() y solo necesita asegurarse de que la función no admita punteros nulos, simplemente pase una referencia, por ejemplo void foo(int &integer). Para los compiladores que conozco, las referencias son la mayoría de las veces punteros que no admiten nulos (que a menudo dependen de las opciones de optimización).

Cuestiones relacionadas