Mon Javaquarium

a marqué ce sujet comme résolu.

Bonjour, j'ai hésité à faire un nouveau post, et comme je débute je pense que vous aurez beaucoup de choses à dire. Le code se trouve ici: https://github.com/Nekyia/Javaquarium.

Il n'y a pour l'instant que l'exercice 1.1. Je veux que chaque partie soit "parfaite" avant de passer à la suivante. Aussi je viens juste de commencer les class hier, donc c'est tout frais.

Voilà. Soyez impitoyable :)

+0 -0

Salut j'ai lu ton code en diagonal ,et apparemment tu ne fais pas la différence entre un objet ayant une sémantique de valeur et un objet ayant une sémantique d'entité ce qui est un peu normal si tu as commencé les classes il y a deux jours.
Je te conseille d'aller voir ça.
Bonne continuation :)

Par exemple dans ton code un poisson est une sémantique d'entité ,cela implique que chaque poisson est unique et que tu ne peux pas les copier (utiliser l'opérateur = ),pour éviter de les copier tu peux utiliser une référence ou un pointeur sur tes poissons.
Exemple :

1
2
3
4
5
6
7
class Aquarium
{
  public: 
  //...
  private :
   vector<unique_ptr<Poisson>> poissons //On utilise un pointeur intelligent pour qu'ils ne soient pas copiés et préserver leur unicité et éviter le problème de slicing si tu utilise l'héritage.
}
+0 -0

Je dis peut-être n'importe quoi, mais est-ce qu'une fonction b.clone(a) qui dit simplement que mon objet b n'est pas le même que le a, mais que c'est un clone et qu'il a donc les mêmes caractéristiques au moment du clonage, à un sens en sémantique d'identité ?

Si j'ai bien compris tu voudrais faire quelque chose comme :

1
2
3
4
  Fish *clone(Fish *f)
  {
     return new Fish(*f);
  }

Si c'est ce que tu voulais faire selon moi ce n'est pas compatible car tu vas utiliser le constructeur de copie de Fish et un objet ayant une sémantique d'entité ne peut pas être copié.

+0 -0

Bonjour,

Un moyen plus simple de respecter la sémantique d'entité pour moi est de supprimer le constructeur par copie et l'opérateur = de la manière suivante :

1
2
3
4
5
class Foo {
public :
      Foo(Foo &autre) = delete;
      Foo& operator=(Foo &autre) = delete;
};

Après, faire des clones, oui mais s'ils sont semblables en tout point, ce sont deux entités différentes et distinguables donc il faut que tu trouves un moyen de les différencier (avec un ID par exemple).

+0 -0

Cela permet d'améliorer la conception de ton programme et donner un sens aux classes ,par exemple il est logique de définir l'opérateur + pour une classe matrice (car sémantique de valeur ) en revanche additionner des poissons n'a pas de sens (sémantique d'entité ) et cela permet aussi d'éviter le slicing .

+0 -0

Après, faire des clones, oui mais s'ils sont semblables en tout point, ce sont deux entités différentes et distinguables donc il faut que tu trouves un moyen de les différencier (avec un ID par exemple).

Si tu supprimes le constructeur de copie et l'opérateur d'affectation je ne sais pas comment tu comptes faire le clonage.

+0 -0

Bah en faisant un constructeur qui prend en paramètres nom, sexe, age, espèce, etc. et qui crée un ID unique pour le poisson et ensuite faire une fonction membre qui crée un nouveau poisson en passant en argument au constructeur le nom du poisson, son sexe, etc.

Rapidement cela pourrait être ça :

1
2
3
4
5
6
7
class Poisson {
public :
   Poisson(std::string name,...);
   getName();
private :
   std::string m_name;
};

avec une fonction cloner :

1
2
3
4
void cloner(Poisson &autre) {
   Poisson clone{autre.getName(),...};
   //puis le mettre dans l'aquarium
}
+0 -0

Ah oui j'avais pas pensé à cette façon de faire ^^
Par contre cela implique beaucoup de getter pas très OO tout ça ;) Moi j'aurais pluôt vu le code comme ça :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Fish
{
   public :

   Fish(const string &n) : nom(n), id(generer_id())
   {

   }

   Fish *clone()
   {
     return new Fish(nom,...,generer_id());
   }

  private :
  int generer_id()
  {
    id=...;
  }

  private :
  string nom
  int id;
}
+1 -0

Merci pour le lien Typhlos. Ça parle de beaucoup de chose que je n'ai pas encore vu mais j'ai marqué la page pour y revenir de temps en temps. Si j'ai bien compris ça permet surtout d'organiser son code pour que lorsque le programme grossit il reste organisé correctement et les objets soient utilisés de manière logique.

Mais je suis encore victime de confusion, reformulons:

1) si un objet est défini par ses valeurs (par exemple une couleur avec les membres R G et B) alors si je copie une instance j'obtiens un double du même objet (deux fois la couleur rouge)

2) sinon (par exemple un homme avec une taille et un âge) si je le copie j'obtiens une autre entité qui a les mêmes valeurs (deux hommes)

=> 1 a une sémantique de valeur et 2 une sémantique d'identité ? je ne peux pas additionner deux hommes et l'égalité n'a pas de sens, ce sont deux entités distinctes. Je peux juste comparer leurs tailles ou leurs âges. (est-ce que ça un sens d'additionner deux couleurs ?)

+0 -0

1) Oui
2) Si tu copie tu n'as plus de sémantique d'identité car tu as perdu l'unicité de ta première entité :chaque entité est unique en les copiant elles ne le seront plus.C'est pour ça qu'il ne faut pas copier les objets ayant des sémantiques d'entités

est-ce que ça un sens d'additionner deux couleurs ?

Oui car une couleur peut être considérée comme une valeur.

Oui c'est vrai qu'on peut faire de la fonction cloner une fonction membre de la classe Poisson. C'est plus propre en effet ;)

Par contre plutôt que new j'utiliserai plutôt std::make_unique<Fish> Fish(nom,…,generer_id()) et la fonction cloner serait plutôt du type std::unique_ptr<Fish>.

+1 -0

Lu'!

Encore une question: que se passe-t-il (que se passera-t-il surtout) si je ne respecte pas cette sémantique d'entité ?

matthieuj

En soi, rien, ton compilateur ne va pas te crier dessus, ton programme va fonctionner mais c'est une norme de la programmation orientée objet.

Typhlos

Non. Ce n'est pas une norme. Ce sont des noms, posés sur des concepts pour différencier leur comportement. D'un côté on a posé les valeurs et de l'autre les entités. Et c'est dû au fait que C++ autorise la copie des objets que l'on a besoin de faire cette distinction dans l'implémentation puisqu'en Java ou en C# par exemple, les objets sont nécessairement des entités puisqu'il n'y a pas de copie d'objet, juste des références.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte