Désolé pour le délai.
Le cours que vous suivez me semble bon. (Il jouit d'une bonne réputation dans les forum C++)
Que vous ayez des difficultés à tout comprendre du premier coup, et même avec beaucoup de relecture, c'est normal. Il n'y a rien d'évident dans tout cela.
Je ne pense pas mieux expliquer que ce cours dans les "courts" messages que constitue cette "conversation" de forum.
Vous semblez un peu suivre leurs conseils récemment. (ou c'est à force de vous bassiner avec dans mes précédents messages.)
Vos dernières modifications (transfert de la fonction "const Episode* SequenceVisionnage::Une_Fonction_De_La_Classe_SequenceVisionnage_xxx(...)" à la fonction "void Episode::Une_Fonction_De_La_Classe_SequenceVisionnage_xxx(...)") montre que le concepts d'interface publique d'une classe n'est pas forcément très bien maîtrisé.
Comme c'est moi qui aie "créé" la fonction initiale, c'est peut-être que vous n'avez pas compris le propos de cette fonction.
Le propos de ces fonctions "Une_Fonction_De_La_Classe_xxx", c'est juste des fonctions membres d'une classe ou d'une autre (cf. le nom de la classe dans le nom de la fonction) pour illustrer le fait que chaque classe dispose d'une "interface publique" distincte que l'on peut façonner à ses besoins.
Une fonction "membre" de l'interface publique de la classe "SequenceVisionnage" n'a pas de sens dans une autre classe comme "Episode".
Le nom de ces fonctions n'était peut-être pas très pertinent, c'était juste à titre pédagogique, pour montrer l'utilisation d'une "interface publique" d'une classe dans le code d'une autre classe.
Comme déjà indiqué, implémenter correctement la fonction "int Episode::GetNumeroSequenceVisionnage(const SequenceVisionnage& sev_vis)" se révèle assez complexe.
Vous n'en avez pas vraiment besoin si vous utilisez les fonctions "void Episode:rintFirstSequenceVisionnage(const SequenceVisionnage& vis)" et "void Episode:
rintSequenceVisionnage(const SequenceVisionnage& vis)" qui seront beaucoup plus simple à faire.
(Et d'un point de vue conception générale, externaliser l'affichage d'un objet dans la console est souvent bien mieux que de l'intégrer à l'interface publique de la classe.)
Pouvons-nous mettre au point ces 2 fontions "Print" avant de revenir sur "GetNumeroSequenceVisionnage" ?
J'espère ne pas vous avoir dit d'utiliser des pointeurs. On verra leurs usages plus tard, si c'est nécessaire.Google :
c++ pointeur et fonction
c++ pointeur sur fonction
c++ pointeur par fonction
c++ pointeur avec fonction
Pour les messages d'erreur, pas de panique. On verra après pour "GetNumeroSequenceVisionnage" (faut juste comprendre le nom de la fonction => donc son type de valeur de retour).
A cette question précise : je vous pose une autre question :Comment fait ?
Struct SequenceVisionnage, ou struct Episode ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part auto NumeroSequenceVisionnage = m_episode.GetNumeroSequenceVisionnage(*this); // ??? #804
"logiquement", quel objet peut savoir si une séquence de visionnage est la première d'un épisode, la seconde ou la troisième ?
Pour moi, c'est l'épisode qui trie "ses" séquences de visionnage, donc "GetNumeroSequenceVisionnage" devrait être une fonction de la classe Episode.
Vous pouvez vous dire que non, que votre logique fait que c'est à la classe "SequenceVisionnage" de connaitre "son" ordre, mais c'est, pour moi, moins "naturel" mais aussi beaucoup beaucoup plus de boulot pour rendre ces numéros "cohérents".
Ben non Quoi ???L'exemple (serie.cpp) :
Ben non !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 void Serie::initialiser_Titre(fs::path const& cheminFichier, std::vector<std::wstring>& m_titre) { // Titre ... std::wregex filename_pattern{ L"(.+?)(?:\\.\\[(\\d{4}\\-\\d{4}\\s?|\\d{4}\\-\\s?|\\d{4}\\s?)?([^\\]]*)\\])?(?:\\.(.+))?" }; std::wsmatch match; if (std::regex_match(contenu[0], match, filename_pattern)) { t.push_back(match[1]); if (match.length() > 2) { t.push_back(match[2]); } if (match.length() > 3) { t.push_back(match[3]); } } else { t.push_back(contenu[0]); } ... }
L'expression régulière "filename_pattern" est là pour extraire les information du nom du fichier, d'où le nom de la variable "filename_pattern".
Ici, la variable "contenu" n'est pas le nom du fichier mais son contenu, qui ne respecte donc pas les mêmes expressions régulières.
Soit vous vous basez sur le contenu du fichier et il vous faut des expressions régulières proches de celles utilisées dans la fonction "void Saison::initialiser_Titre(std::filesystem::path const& cheminFichier)" comme "titre_pattern" et pas de "filename_pattern".
Soit vous vous basez sur le nom du fichier pour avoir ces informations supplémentaires, vous devez alors légèrement modifier "filename_pattern" pour les récupérer. Mais des caractères comme ":" et "/" posent des problèmes dans les noms de fichier dans les systèmes de fichiers "classiques"/Windows. Cela explique que les expressions régulières sur les NOMS de fichiers ne sont pas les mêmes que sur le CONTENU de fichiers.
En résumé, vous appliquez les expressions régulières aux mauvaises données.
Vous pouvez être plus à l'aise avec des "find" qu'avec des expressions régulières mais si vous les appliquez "mal", l'une comme l'autre, ne fonctionneront pas.
Ici, "find" fonctionne parce que vous appliquez la "bonne" formule aux bonnes données, mais les expressions régulières fonctionnent aussi bien ( même mieux) si vous appliquez les "bons" patterns/motifs aux bonnes données.
Ne disqualifiez pas les expressions régulières parce que vous vous en servez mal et sur les mauvaises données.
Les 37 lignes de code "L'exemple :" sont facilement remplaçables par les ~10 lignes au cœur de "void Saison::initialiser_Titre(std::filesystem::path const& cheminFichier)" tout en étant plus lisible, plus flexible, "sans" bugs (le code à base "find" gère très mal de nombreux cas).
Donc :
Pas OK, car le problème n'est pas là où vous croyez.Ok ou pas ?
Partager