2010-08-28 13 views
9

Estoy empezando a escribir una biblioteca y teniendo en cuenta su interfaz. Las bibliotecas anteriores que he escrito utilizan punteros sin procesar (tanto internamente como en su interfaz), y ahora quiero probar la biblioteca del puntero inteligente que viene con VS2010.¿Debería una biblioteca usar una interfaz que utiliza punteros inteligentes?

  1. ¿La interfaz debe usar punteros inteligentes? (Posiblemente forzando a los usuarios de la biblioteca a usar punteros inteligentes también?)
  2. ¿Sería complicado si la interfaz utiliza punteros sin procesar pero la biblioteca utiliza punteros inteligentes internamente? (¿Es posible? Shared_ptr no tiene un método de liberación() ...)
  3. ¿Se pueden usar de forma intercambiable dos bibliotecas de punteros inteligentes compatibles con C++ 0x (por ejemplo, boost y VS2010)? (Por ejemplo yo uso VS2010 para escribir mi biblioteca y los usuarios usar Boost)

favor ayuda :)

+4

1. Sí, forza a tus usuarios a formar buenas prácticas de programación. :) – GManNickG

Respuesta

5

Es imposible contestar esas preguntas sin entender mucho más sobre sus principios de diseño y cómo espera que se use la biblioteca.

Así que solo puedo responder en función de mi experiencia y de cómo me gusta que se utilicen mis bibliotecas.

  1. Sí.
  2. Sí. No lo hagas
  3. Probablemente no sea una buena idea mezclarlos (aunque nunca lo he intentado).
    Pero puede compensar esto:
    Como la mayoría de las fuentes abiertas se distribuyen como fuente, puede construir su fuente para que pueda configurarse para su uso en muchos entornos.

Por ejemplo:

#if defined(MY_PROJ_SHARED_PTR_FROM_BOOST) 

#include <boost/shared_ptr.hpp> 
#define MY_PROJ_SHARED_PTR_NAMESPACE boost 

#elif defined(MY_PROJ_SHARED_PTR_FROM_STD) 

#include <memory> 
#define MY_PROJ_SHARED_PTR_NAMESPACE std 

#elif defined(MY_PROJ_SHARED_PTR_FROM_TR1) 

#include <tr1/memory> 
#define MY_PROJ_SHARED_PTR_NAMESPACE std::tr1 

#else 
#error "MY_PROJ_SHARED_PTR_FROM_<XXX> not defined correctly" 
#endif 


namespace X 
{ 
    using ::MY_PROJ_SHARED_PTR_NAMESPACE::shared_ptr; 
} 


int main() 
{ 
    X::shared_ptr<int> data; 
} 

Estoy seguro de que hay otras maneras de hacer esto.
Pero es tarde.

0
  1. Depende de la si se tiene en cuenta # 2 y # 3 más importante.
  2. Sí.
  3. No, a menos que hayan sido deliberadamente diseñados para.
0

Yo diría que use la regla 80-20 aquí. Si el 80% de los clientes prefieren usar boost/stl/C++, entonces hágalo. Por lo demás, puede construir la capa de adaptador y mover la complejidad a esa capa. El patrón de diseño del Adaptador es mi favorito para tales fines.

0

Desde el punto de vista de un usuario, diría que solo tiene que tener en su interfaz la información clara sobre lo que necesita.

¿Necesita una copia del objeto o simplemente un puntero?

Internamente, probablemente pueda usar el tipo de puntero que le resulte más conveniente, siempre que no se degrade demasiado el rendimiento y no cause errores.

Una pregunta para hacer es ¿qué harás exactamente con ese puntero? ¿Lo eliminarás? ¿Puedo cambiar la referencia si actualizo/elimino el objeto (digamos en el caso de una biblioteca GUI).

Como alguien que no suele utilizar punteros inteligentes cuando no es necesario ver demasiados punteros inteligentes, simplemente me dirá que no presta atención a lo que hará y es la causa de posibles errores.

Como usuario de la biblioteca, prefiero un bloqueo (cuando intento desreferenciar un puntero claramente no válido) tener un puntero semi-válido que no es realmente lo que esperaba (que sospecho que puede ser un problema con el uso de punteros inteligentes de el tipo shared_ptr).

+0

"Como alguien que no suele usar punteros inteligentes cuando no se necesitan ver demasiados punteros inteligentes, simplemente me dirá que no prestas atención a lo que harás" Correcto. ¿Me puede decir una situación en la que no debe envolver un puntero? – GManNickG

+1

¿Puede decirme una situación cuando debería? Normalmente, la propiedad se evalúa fácilmente y un scoped_ptr es suficiente. Otros punteros son solo alias y no necesitan punteros especiales. Creo que podría haber una situación en la que un shared_ptr sea útil, pero, de lo contrario, te lanzaría el balón y te preguntaría por qué quieres usar un shared_ptr tú mismo. Normalmente no tengo tantos problemas para mantener la propiedad de mis punteros y saber cuándo puedo eliminarlos o no. – n1ckp

+1

@ n1ck: Uh, cada situación. Tengo un recurso, necesito asegurarme de que se publique, tanto frente al olvido como a las excepciones. La única forma de hacerlo es en un destructor. ¿Por qué * no * yo? Quisiera un puntero compartido porque tengo un recurso compartido ... y no quiero preocuparme cuando se lo libere, solo quiero saber que va a ser. La única situación en la que puedo pensar es en un puntero no propietario (que de todos modos estaría incluido en alguna utilidad, que está usando el puntero no propietario para un propósito). – GManNickG

Cuestiones relacionadas