2010-07-11 25 views
5

Así que he estado pensando en PIMPL y la asignación de la pila. He estado escribiendo una biblioteca y decidí usar PIMPL para ocultar al miembro privado de la clase. Eso significa que tendría una clase declarada asíPIMPL y la asignación de la pila

class Foo { 
private: 
    class Handle; 
    std::tr1::shared_ptr<Handle> handle; 
public: 
    Foo(); 
}; 

Es bastante sencillo. Pero entonces en el constructor de hacer esto

Foo::Foo() : handle(new Handle()) {} 

Así que cuando alguien usando mi biblioteca crea un Foo en la pila, que están haciendo esencialmente una asignación del montón de todos modos. ¿Es este el compromiso con el que tienes que vivir cuando usas PIMPL? Pensé en lanzar la documentación con una advertencia al lado de los constructores: "ADVERTENCIA: Esto da como resultado una asignación de montón" o algo así.

Mi otro pensamiento fue tener todas las clases que están expuestas a la implementación como interfaces virtuales puras y un montón de métodos de fábrica estáticos que devuelven punteros inteligentes. Esto también significa asignación de montón, pero no hay ningún truco para eso.

¿Algún comentario o sugerencia? ¿Soy demasiado considerado con los programadores que usan mi biblioteca?

+1

El problema con tal advertencia es que una gran cantidad de operaciones resultan en asignaciones de montón. Crear un 'std :: vector' también lo hace. O cambiar el tamaño de uno. La compensación es cuán importante es esconder las partes internas de la clase, en comparación con el rendimiento adicional de evitar las asignaciones de pila. – jalf

Respuesta

4

¿Es este el compromiso con el que tiene que vivir cuando usa PIMPL?

Efectivamente, sí, aunque hay técnicas, tales como los discutidos por Herb Sutter en "The Fast Pimpl Idiom," que se puede utilizar para eliminar o acelerar la asignación de montón, a costa de una mayor complejidad.

Pensé en liberar la documentación con una advertencia al lado de los constructores: "ADVERTENCIA: Esto da como resultado una asignación de montón" o algo así.

Solo si es necesario hacerlo (es decir, solo si los usuarios se sorprenden por el hecho de que su clase realizó la asignación de montón). Muchas clases realizan asignaciones de montón, incluidas muchas de las que se encuentran en la biblioteca estándar de C++ (todos los contenedores, por ejemplo).

¿Soy demasiado considerado con los programadores que usan mi biblioteca?

Posiblemente :-). A menos que tengas requisitos de alto rendimiento para tu clase o esperes que se creen y destruyan instancias de tu clase con demasiada frecuencia, no me preocuparía demasiado. Por supuesto, si tiene requisitos de rendimiento significativos, pimpl puede no ser una buena opción.

+0

Genial, gracias. Voy a ver como Fast Pimpl de todos modos porque se ve interesante. – Anthony

4

Así que cuando alguien que usa mi biblioteca crea un Foo en la pila, en esencia están haciendo una asignación de montón. ¿Es este el compromiso con el que tienes que vivir cuando usas PIMPL?

Yep.

Pensé en liberar la documentación con una advertencia al lado de los constructores: "ADVERTENCIA: Esto da como resultado una asignación de montón" o algo así.

yo consideraría que más agresiva comentar :) Si su clase es tan crítica de rendimiento, tal vez se debe evitar el lenguaje PIMPL.Si estás representando un número, esto podría ser preocupante y digno de mención. Si está ocultando la implementación de una conexión de base de datos, no vale la pena el comentario :)

Mi otro pensamiento era tener todas las clases que están expuestas a la implementación como interfaces virtuales puras y un montón de métodos de fábrica estáticos regresando punteros inteligentes. Esto también significa asignación de montón, pero no hay ningún truco para eso.

Sí, es un poco más obvio para el usuario, pero de nuevo probablemente no valga la pena preocuparse.

¿Algún comentario o sugerencia? ¿Soy demasiado considerado con los programadores que usan mi biblioteca?

Hay una compensación, pero si su clase es lo suficientemente compleja como para realmente beneficiarse de la expresión de pimpl, probablemente pueda asumir que una asignación de montón está bien. Si estuviera usando tu biblioteca, probablemente no me preocupe.

+0

Genial, gracias. Seguiré haciendo lo que estoy haciendo. – Anthony

Cuestiones relacionadas