2009-10-05 13 views
5

[EDIT 1 - troisième syntaxe de pointeur ajoutée (Merci Alex)]C++ DAL - Retour de référence ou POPULATE Passed En référence

Quelle méthode préférez-vous un DAL et pourquoi de:

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

Si incapable de trouver la première méthode de voiture renvoie null, la deuxième méthode renvoie false.

La seconde méthode créerait un objet Car sur le tas et remplirait avec des données interrogées à partir de la base de données. On peut supposer que (mon C++ est très rouillée) qui signifie le code le long des lignes 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; 
} 

Merci

Répondre

5

Le second est certainement préférable. Vous renvoyez une référence à un objet qui a été modifié. Pour un utilisateur final utilisant le logiciel, il n'est pas évident que l'objet retourné nécessite une suppression. PLUS si l'utilisateur fait quelque chose comme ceci

Car myCar = dal.loadCar(id); 

Le pointeur se perdrait.

Votre seconde méthode place donc le contrôle de la mémoire sur l'appelant et empêche toute erreur bizarre.

Éditer: Le retour par référence est sensible mais seulement lorsque la classe parente, c'est-à-dire DAL, contrôle la durée de vie de la référence. c'est-à-dire que si la classe DAL avait un vecteur d'objets Car, alors renvoyer une référence serait une chose parfaitement sensée à faire.

Édition2: Je préférerais toujours la deuxième mise en place. Le 3ème est bien meilleur que le premier mais vous finissez par faire supposer que l'objet est initialisé.

Vous pouvez également fournir

Car DAL::loadCar(int id); 

et espoir accepter la copie de la pile. N'oubliez pas non plus que vous pouvez créer une sorte d'objet voiture null pour que vous retourniez un objet qui soit "valide" mais qui ne vous renvoie aucune information utile dans tous les champs (et donc qui est évidemment initialisé aux données d'ordures). C'est le modèle d'objet nul.

+0

Merci. Même si l'appelant a écrit "Car & myCar = dal.loadCar (id)" le pointeur ne serait-il pas perdu? Y a-t-il un code non DAL pour supprimer la mémoire créée par le DAL? – ng5000

+0

Non si l'appelant a écrit ce que vous venez d'écrire, la mémoire "pourrait" être libérée. Vous devez appeler "supprimer &myCar;" pour le faire si ... ce qui semble très étrange. – Goz

+0

La copie de la pile ne peut même pas arriver: en fonction du compilateur et des optimisations, le RVO (N) peut démarrer et rendre l'opération équivalente à # 1. Dans tous les cas, lancer une exception lorsque la voiture n'est pas trouvée sera nécessaire. –

4

Puisque vous êtes en train d'allouer des objets sur heap, pourquoi ne pas considérer Car * LoadCar() qui retourne NULL en cas de problème. De cette façon, vous n'avez aucune restriction avec les types de référence (chaque référence doit être initialisée) et avez également des moyens pour signaler le cas d'erreur.

+0

Semble raisonnable, question mise à jour pour ajouter une 3ème option. – ng5000

+0

Car & DAL :: loadCar (int id) ne peut pas renvoyer NULL; il n'y a pas de référence nulle, seulement des pointeurs NULL. – Massa