2009-10-05 7 views
5

[EDIT 1 - añadió sintaxis tercer indicador (Gracias Alex)]C++ DAL - Retorno de referencia o pueblan aprobada en referencia

Qué método prefiere para una DAL y por qué de:

Car& DAL::loadCar(int id) {} 
bool DAL::loadCar(int id, Car& car) {} 
Car* DAL::loadCar(int id) {} 

Si no puede encontrar el automóvil, el primer método devuelve nulo, el segundo método devuelve falso.

El segundo método crearía un objeto Car en el montón y lo poblaría con los datos consultados desde la base de datos. Es de suponer que (mi C++ es muy oxidada) que significaría código a lo largo de las líneas de:

Car& DAL::loadCar(int id) 
{ 
    Car *carPtr = new Car(); 
    Car &car= *carPtr; 
    car.setModel(/* value from database */); 
    car.setEngineSize(/* value from database */); 
    // etc 
    return car; 
} 

Gracias

Respuesta

5

La segunda es claramente preferible. Está devolviendo una referencia a un objeto que se ha renovado. Para un usuario final que usa el software, no es obvio que el objeto devuelto requiera su eliminación. MÁS si el usuario hace algo como esto

Car myCar = dal.loadCar(id); 

El puntero se perdería.

Su segundo método, por lo tanto, pone el control de la memoria en la persona que llama y evita que ocurran errores extraños.

Editar: El retorno por referencia es sensato, pero solo cuando la clase primaria, es decir, DAL, tiene control sobre la duración de la referencia. es decir, si la clase DAL tenía un vector de objetos Car en él, devolver una referencia sería una cosa perfectamente sensata.

Edit2: Yo preferiría la segunda configuración. El tercero es mucho mejor que el primero, pero al final haces que quien llama asuma que el objeto se inicializó.

También podría proporcionar

Car DAL::loadCar(int id); 

Y la esperanza aceptar la copia pila.

Además, no olvide que puede crear un tipo de objeto null para que devuelva un objeto que sea "válido" pero no le devuelva información útil en todos los campos (y por lo tanto, se inicializa a datos basura)) Este es el Patrón de Objeto Nulo.

+0

Gracias. Incluso si la persona que llama escribió "Car & myCar = dal.loadCar (id)", ¿no se perdería el puntero? ¿Hay alguna forma para el código que no es DAL de eliminar la memoria creada por el DAL? – ng5000

+0

No, si la persona que llamó escribió lo que acaba de escribir, la memoria "podría" ser liberada. Tendría que llamar a "eliminar &myCar;" para hacerlo ... lo que parece muy extraño. – Goz

+0

La copia de la pila puede que ni siquiera suceda: según el compilador y las optimizaciones, el (N) RVO podría activarse y hacer que la operación sea equivalente a la # 1. En cualquier caso, será necesario lanzar una excepción cuando no se encuentre el auto. –

4

Dado que de todos modos está asignando objetos en montón, ¿por qué no considerar Car * LoadCar() que devuelve NULL si se produce un problema. De esta manera no tiene restricciones con los tipos de referencia (cada referencia debe estar inicializada) y también tiene medios para señalar el caso de error.

+0

Suena una pregunta razonable y actualizada para agregar una tercera opción. – ng5000

+0

Car & DAL :: loadCar (int id) no puede devolver NULL; no hay referencia nula, solo punteros nulos. – Massa

Cuestiones relacionadas