Tengo algunos proyectos que usan boost::shared_ptr
o std::shared_ptr
extensamente (puedo convertir a cualquier implementación lo suficientemente pronto, si hay una buena respuesta a esta pregunta para uno, pero no para el otro). La implementación de Boost usa Boost.Assert para evitar el retorno en el caso de encontrar un puntero vacío (NULL) en operator*
o operator->
en tiempo de ejecución; mientras que la implementación de libC++ parece carecer de cualquier control.Personalizar std :: shared_ptr o boost :: shared_ptr para lanzar una excepción en NULL deferencia
Si bien, por supuesto, la validez de un shared_ptr
debe verificarse antes de su uso, una base de código de paradigma mixta grande me lleva a desear probar una variación de arrojar excepciones; ya que la mayor parte del código es relativamente sensible a las excepciones y, como mucho, fallará en un estado de alto nivel pero reanudable, en lugar de std::terminate()
o segfault.
¿Cómo puedo personalizar mejor estos accesos mientras mantengo la robustez de shared_ptr
? Parece que encapsular shared_ptr
en un throwing_shared_ptr
puede ser la mejor opción, pero soy cauteloso de romper la magia. ¿Es mejor que copie la fuente de Boost y simplemente cambie el ASSERT
a una declaración apropiada de throw
?
El nombre de tipo real que se utiliza en todas partes para el apropiado tipo smart_ptr<T>
es un typedef expandido desde una macro; es decir, ForwardDeclarePtr(Class)
amplía a algo como:
class Class;
typedef boost::smart_ptr<Class> ClassPtr;
Todo pasa, toma, o almacena un ClassPtr
- para que pueda reemplazar el tipo subyacente con bastante libertad; y sospecho que esto alivia el posible problema de corte/ocultación.
Aceptando esta respuesta porque es un poco más fácil explicar el diseño, la seguridad y el uso de la encapsulación en los comentarios (las clases tienen miembros 'shared_ptr' todo el tiempo). @KevinBallard también es correcto, sin embargo. – rvalue