2012-04-27 10 views
5

Estoy usando scoped_ptr dentro de pequeñas funciones como esta. para que no tenga que llamar borrar ¿Es esto una exageración para este uso? Los miembros de mi equipo prefieren punteros sin procesar y eliminar. ¿Cuál es el costo de usar scoped_ptr si se utiliza en una ruta muy crítica? ¿No debería estar alineado y ser exactamente equivalente a simplemente usar la eliminación normal en binario optimizado?¿Es excesivo usar scoped_ptr en casos simples?

void myfunc() 
{ 
    boost::scoped_ptr<myobj> objptr = someFactory::allocate(); 
    callsomeotherfunc(objptr.get()); 
} 

Respuesta

8

estoy seguro del impacto en el rendimiento, pero utilizando scoped_ptr aquí asegura myfunc() es segura excepción: si se produce una excepción callsomeotherfunc() todavía se liberó a la memoria asignada dinámicamente. Si scoped_ptr no se utilizó y callsomeotherfunc() podría lanzar entonces la función tendría que ser estructurado similar a esto:

void myfunc() 
{ 
    myobj* objptr = someFactory::allocate(); 

    try 
    { 
     callsomeotherfunc(objptr); 
     delete objptr; 
    } 
    catch (const some_exception&) 
    { 
     delete objptr; 
     throw; 
    } 
} 

Ésta es propenso a errores, como todos los futuros modificaciones de la función necesitarían para asegurar que delete objptr; se invoca en todas las posibles puntos de salida

+1

espero 'impulsar :: scoped_ptr' sea lo más rápida en el caso no excepcional y mucho más rápido en el excepcional el ala es costosa con el modelo moderno ZeroCost). –

0

No, no lo es. El beneficio de usar puntero inteligente (por ejemplo, seguridad de excepción y limpieza automática de recursos) es mucho mayor que la pérdida de rendimiento de usar un par de bytes adicionales de memoria y un par de relojes de CPU adicionales necesarios para la creación, mantenimiento y destrucción de punteros inteligentes.

+0

.. excepto si la función llega a un punto en el que la seguridad de la excepción y la limpieza automática de los recursos no deben suceder. ¿Supongo que al establecer el puntero inteligente como nulo, se evitaría la limpieza? –

+0

@Martin Esa es una idea interesante, pero no puedo pensar en ningún caso cuando la seguridad de las excepciones y la limpieza automática de los recursos no son deseables. ¿Podría darnos algún ejemplo? –

+0

Seguro, fácil: renombrar 'callsomeotherfunc (objptr);' a 'queueObjectToOutputThread (objptr);'. Ahora, la limpieza automática de los recursos provocará una desastrosa AV/segfault, probablemente en algún lugar en otro módulo, ejecutada por otro hilo, no relacionado con el módulo supuestamente "seguro" que causó el problema. –

3

yo no usaría scoped_ptr para tal fin, sino más bien unique_ptr en C++ 11 y auto_ptr en los compiladores de más edad, ambos de los cuales son equivalentes para el caso de uso particular. A partir de si es excesivo, no, no lo es, es la única opción para proporcionar seguridad de excepción (digamos cualquier cosa en el código de myfunc o callsomeotherfunc throws, desea que se libere la memoria). En cuanto a rendimiento, las tres opciones son equivalentes a tener una llamada delete al final de la función en el caso donde no se lanzan excepciones, y más rápido que tener un bloque try/catch con un delete que vuelve a lanzar la excepción en caso de excepciones.

Además, parece que está asignando desde una fábrica, en algunos diseños que la fábrica tendrá una operación deallocate que necesita ser llamada, en lugar de delete. Si ese es el caso, puede considerar un puntero inteligente diferente (shared_ptr del estándar, que sería exagerado si delete es la forma correcta de liberar la memoria, o un poco menos de managed_ptr para el que también puede proporcionar un eliminador)

+0

¿Qué beneficio otorga 'auto_ptr' a' scoped_ptr' (aparte de que uno es 'std' y uno es' boost')? – KillianDS

+0

@KillianDS: para este caso particular, ninguno. Pero es estándar y no trae una dependencia externa adicional, y en este caso es una solución válida. –

+1

@ DavidRodríguez-dribeas: la semántica de 'boost :: scoped_ptr' es bastante diferente de la de' std :: unique_ptr'. Una propiedad notable de 'scoped_ptr' es agregar un significado semántico en beneficio del lector: este recurso no escapará a este alcance. –

0

creo que el equivalente a scoped_ptr uso sería:

void myfunc() 
{ 
    myobj* objptr = someFactory::allocate(); 
    try 
    { 
     callsomeotherfunc(objptr); 
    } 
    catch (...) 
    { 
     delete objptr; 
     throw; 
    } 
    delete objptr; 
} 

yo sé qué versión preferiría escribir ...

+0

no es equivalente, la versión 'scoped_ptr' no volverá a aparecer debido al desenrollado de la pila. – KillianDS

Cuestiones relacionadas