Ma première question est la suivante : est-ce une mauvaise pratique de rendre le tableau d'objets Carte public dans la classe Deck ?
Oui. En général, les membres des données doivent toujours être privés. Dans le cadre de la POO, il est bon de créer une interface sans données associées qui définit les opérations pouvant être effectuées sur l'objet, puis de fournir une classe concrète qui implémente cette interface. Les données sont un détail d'implémentation qui ne doit pas être visible dans l'interface ou même dans la classe entièrement concrète. À titre d'exemple, vous pouvez implémenter votre classe en utilisant un tableau d'objets Carte pour le moment, mais vous déciderez peut-être plus tard d'utiliser un jeu de bits où un seul bit indique si la carte est ou n'est pas présente dans le jeu. Si vous rendez votre objet tableau de cartes public, le fait de modifier la représentation de cette manière perturberait les autres utilisateurs de votre classe ; en revanche, si vous le gardez privé, vous pouvez effectuer ce changement sans que cela ait un impact sur les utilisateurs de votre classe.
Une autre question : Comment les objets, tels que l'objet Carte utilisé dans mon programme de blackjack, sont-ils généralement déplacés de l'intérieur d'un objet - comme le croupier - vers un second objet comme un joueur ?
Cela dépend si l'autre objet a besoin d'accéder à l'objet carte original, si l'autre objet conservera l'objet original pendant une longue ou une courte période, ou si l'autre objet ne peut manipuler qu'une copie de la carte. Cela dépend également du fait que la carte soit une classe concrète ou un type polymorphe, car les objets polymorphes ne peuvent être transmis que par pointeur ou par référence (car transmettre des objets polymorphes par valeur entraînera un découpage du code). Avec les objets concrets, vous avez la possibilité de transmettre une copie, sauf si vous devez modifier ou accéder à l'objet original, auquel cas une référence est nécessaire. Le choix de la bonne façon de transmettre des objets est quelque peu compliqué, mais nous espérons que cela vous éclairera :
Passez par valeur si :
C'est un type primitif ou un petit type concret non polymorphe qui n'a pas besoin d'être modifié.
Passer par référence constante -- c'est-à-dire const T&
pour un certain type T
-- si :
- Il n'est pas nécessaire de modifier l'objet original.
- Il n'est pas nécessaire de lire l'objet original en dehors de la portée de la fonction.
- Il n'est pas nécessaire de lire l'objet au-delà de la portée de la fonction, ou du type est non polymorphe et peu coûteux à copier, vous pouvez donc créer une copie si vous avez besoin de vous y accrocher. l'objet.
Passer par référence -- c'est-à-dire T&
pour un certain type T
-- si :
- Vous devez modifier l'objet original.
- Il n'est pas nécessaire de lire/écrire l'objet original en dehors de la portée de la fonction.
- Vous n'avez pas besoin de lire l'objet au-delà de la portée de la fonction, ou du type est non polymorphe et peu coûteux à copier, vous pouvez donc créer une copie si vous avez besoin de vous y accrocher. l'objet.
Passer par constante pointeur intelligent vers une constante -- c'est-à-dire const shared_ptr<const T>&
pour un certain type T
-- si :
- Vous devez lire l'objet original à la fois dans la portée de la fonction et au-delà.
- Vous devez lire l'objet à la fois dans la portée de la fonction et au-delà, et le type est non polymorphe de sorte qu'il n'est pas possible d'en créer une copie en toute sécurité.
Passer par un pointeur intelligent constant -- c'est-à-dire const shared_ptr<T>&
pour un certain type T
-- si :
- Vous devez lire et écrire l'objet original à la fois dans le cadre de la fonction et au-delà.
J'ai donné chacun des éléments ci-dessus dans un ordre délibéré ; vous devez essayer le premier qui vous convient, et ne passer au suivant que si le précédent ne suffit pas. Je dois également ajouter que boost::call_traits<T>::param_type peut vous aider à choisir entre le passage par valeur et le passage par référence constante dans le cas de types concrets non polymorphes (il peut déterminer, en fonction de la taille de l'objet, si le passage par valeur ou le passage par référence constante est préférable).