2011-01-20 20 views
5

Me gustaría saber qué se considera hoy en día mejor práctica al devolver un puntero a un objeto polimórfico de una función, por ejemplo, al usar fábricas. Si transfiero la propiedad, ¿debo devolver boost::unique_ptr<Interface>? ¿Qué debo devolver si no transfiero la propiedad (por ejemplo, devolver una referencia a un miembro)? ¿Existe una alternativa, no basada en el impulso que también se usa comúnmente? Gracias.Devolución de objetos polimórficos C++ (interfaces)

EDIT: se supone que es compatible con C++ 03, con la posibilidad de actualizar fácilmente a 0x

Edit2: Tenga en cuenta que estoy pidiendo explícitamente sobre enfoques comunes, mejores prácticas, y no sólo "una manera de hacer esto". Una solución que implique una búsqueda y reemplazo condicional sobre la base del código en el futuro no parece una buena práctica, ¿o sí?

EDIT3: Otro punto acerca de auto_ptr es que está obsoleto, sea lo que sea, por lo que parece extraño anunciar su uso en el nivel de interfaz. Entonces, alguien que no lo sepa colocará el puntero devuelto en un contenedor STL, y así sucesivamente. Entonces, si conoce otra solución que de alguna manera es común, puede agregar una respuesta.

+0

Puede quejarse todo lo que desee acerca de cómo ':: std :: auto_ptr' está en desuso, el hecho es que no se puede mejorar sin la sobrecarga, o el estrechamiento de la interfaz. Si usa ':: std :: tr1 :: shared_ptr' obtendrá recuento de referencias cuando no lo necesite. Realmente ':: std :: auto_ptr' es la única solución razonable disponible en C++. ':: boost :: unique_ptr' simplemente elimina las operaciones problemáticas de' :: std :: auto_ptr'. Y aunque algunos podrían considerarlo mejor, es una biblioteca de terceros, y no podría recomendar el uso de una biblioteca de terceros como una "mejor práctica" a menos que no hubiera otra alternativa. – Omnifarious

+0

@Omnifarious: Agradezco su respuesta, pero también estoy tratando de alentar a otras personas a compartir su opinión. –

+0

¿Hay alguna razón por la que no esté considerando 'shared_ptr' para esto? –

Respuesta

5

Use ::std::auto_ptr por ahora, y cuando C++ 0x esté disponible, cambie a ::std::unique_ptr. Al menos en el caso de la fábrica donde le está devolviendo la propiedad a la persona que llama.

::std::auto_ptr tiene problemas y es feo. Sí, está en desuso en C++ 0x. Pero esa es la forma recomendada de hacerlo. No he examinado ::boost::unique_ptr, pero sin semántica de movimiento no veo que pueda ser mejor que ::std::auto_ptr.

Prefiero la idea de actualizar haciendo una búsqueda y reemplazo, aunque hay algunos casos inusuales en los que eso no tendrá el resultado esperado. Afortunadamente, estos casos generan errores de compilación:

::std::auto_ptr<int> p(new int); 
::std::auto_ptr<int> p2 = p; 

tendrán que ser al menos igual que este

::std::unique_ptr<int> p(new int); 
::std::unique_ptr<int> p2 = ::std::move(p); 

prefiero buscar y reemplazar porque me parece que el uso de macros y typedefs para cosas como esta tienden a hacer cosas más oscuras y difíciles de entender más tarde. Una búsqueda y reemplazo de su base de código se puede aplicar selectivamente si es necesario (::std::auto_ptr no desaparecerá en C++ 0x, simplemente está en desuso) y deja su código con una intención clara y obvia.

En cuanto a lo que se hace 'comúnmente', no creo que el problema haya existido durante el tiempo suficiente como para que haya un método comúnmente aceptado para manejar el cambio.

+2

+1 - 'std :: auto_ptr' es impresionante a pesar de que la gente lo critica todo el tiempo. –

+0

Bueno, pero ¿cómo puedo cambiarlo luego, buscando y reemplazando todo mi código? –

+0

@ 7vies: suponiendo que la dependencia de impulso no es un problema, solo continúe usando boost, excepto donde debe transferir la propiedad. De lo contrario, tendrás que buscar y reemplazar. –

Cuestiones relacionadas