Editar: Los ejemplos dados aquí no respetan la regla de los Tres Grandes (gracias @Philipp!). Si la definición de A se utiliza como se indica a continuación, el código se bloqueará en la construcción de copia para A o en la asignación de A. Para definir correctamente el código, el operador de asignación y el constructor de copia deben definirse explícitamente para A (o explícitamente prohibido: declarado como privado y nunca implementado). (Fin Editar)
¿Debo pasar por valor, por referencia (const), o un puntero?
Si A utiliza B y C, y luego retenerlos por referencia o puntero dentro de A. Para elegir entre la referencia y el puntero, ver cómo B y C están asignados.
Si se trata de objetos de pila local construidos en el mismo ámbito que A, entonces páselos por const referencia.
Si son objetos que utiliza un asignan dinámicamente, hacer una propia ellos: pasar por ellos punteros, y tienen destructor de A a eliminar.
Si son componentes opcionales de A, los pasan por puntero (que puede ser nulo).
Si A no se hace responsable de eliminarlos, páselos por * const
.
¿Dónde debo desasignarlos?
Generalmente, cuando ya no los necesita :).
Si se necesitan más allá del alcance de A (si son objetos externos que A usa), elimínelos cuando se completa el alcance de A.
Si son propiedad de A, elimínelos en el destructor para A. También puede tener sentido eliminarlos durante la vida útil de A, si los punteros deben cambiarse.
Aquí hay un ejemplo, donde B es un componente reemplazable inyectado en A (y propiedad de A) y C es un componente opcional propiedad de A (pero también inyectado en A).
("propiedad de" significa que A es responsable de eliminar los dos objetos)
class B;
class C;
class A
{
B* b;
C* c;
public:
A(B* const bb, C* const cc = 0) // cc is optional
: b(bb), c(cc)
{
}
void resetB(B* const bb = 0)
{
delete b;
b = bb;
}
~A()
{
resetB();
delete c;
}
};
{
A a(new B, new C);
a.resetB(); // delete B
a.resetB(new B); // delete former B and set a new one
} // both members of A are deleted
Pero no sé si es una buena práctica o no. ¿Alguna sugerencia?
Todo depende de que realmente, pero se puede escribir A a(B(1, 2, 4), C(1, 2, 3))
tan fácil como A a(new B(1, 2, 4), new C(1,2,3));
(en el primer caso - el uno sin nueva - la A :: B y A :: c debe ser referencias o objetos/valores dentro la clase, y A no debería eliminarlos en absoluto).
La pregunta no debería ser si desea escribir la declaración con la asignación dinámica para B y C, pero si es necesario. La asignación dinámica es lenta y, si no la necesita, no debería hacerlo.
Ver [_Cómo pasar objetos a funciones en C++? _] (Http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c/2139254#2139254) – sbi