1110

Brunni (./1102) :

Ce n'est pas bon, parce que:
Rectangle c = new Carré(); c.setWidth(10); c.setHeight(20); System.out.println(c.getWidth() + "x" + c.getHeight()); Il est difficile de dire à quoi s'attendre... 20x20 sera le résultat, mais ça aurait pu être 10x10 ou même 10x20 en toute logique (mais à ce moment le carré est dans un état incohérent). Bref c'est pour ça qu'un carré n'est pas un rectangle, d'où ma solution ^^


Bah non, avec ma solution, setWidth et setHeight font exactement la même chose ; le carré aura donc une taille de 20x20 (logique, d'ailleurs... tu étires le carré par un de ses côtés, puis tu changes la taille d'un autre côté : le carré aura un côté de la taille finale, point barre)
avatar

1111

A ce moment là ça c'est logique aussi?
void test(Rectangle c) {
    c.setWidth(10);
    c.setHeight(20);
    c.area();   // aire=400? (si c était un carré...)
}

Je trouve que c'est une grosse incohérence, surtout pour quelqu'un qui lira ton code et qui n'a pas envie de remonter la hiérarchie de la référence 'c' pour savoir si c'est un carré ou un autre objet chelou qui aurait d'autres contraintes bizarroïdes comme celle-ci ^^
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

1112

Bah quelqu'un qui lira mon code avec un bon IDE pourra tout de suite savoir que c est un carré en passant son curseur dessus tongue
avatar

1113

Non ^^
(j'ai édité puisque tu veux pinailler, là ton IDE ne pourra absolument rien faire tongue)
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

1114

Ta syntaxe pourrait être transposée en Java ? (J'arrive pas à trouver d'équivalent, en fait, mais bon, ça fait des plombes que je n'ai pas fait de Java, donc c'est peut être aussi parce que mon cerveau est comme une passoire...)
avatar

1115

(C'est du java en fait, j'ai juste pas mis le public void parce qu'on s'en tape ^^ - mais c'est bien que tu fasses remarquer ça, en C++ il faudrait l'étoile ou le & pour que ça marche, puisque le polymorphisme n'existe pas sur des objets passés par valeur wink)
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

1116

Pas forcément: typedef Rectangle_class &Rectangle; grin
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

1117

(Pas très net tongue je le fais, mais je préfixe toujours d'un C majuscule, et j'en fais une const ref)
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

1118

Bah, évidemment que le ./1116 est du code de porc, je n'ai jamais prétendu le contraire, hein. gni
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

1119

JackosKing, tu apporteras une réponse à ./1105 et les quelques suivants stp ? j'ai juste peur que les posts disparaissent dans la tourmente grin

1120

Brunni > Ah oui, effectrivement, l'absence de public m'a troublée (oui, oui, il m'en faut peu grin).
Cela dit, je ne suis pas d'accord avec toi... ma façon de procéder permet d'utiliser ta méthode test quelle que soit l'instanciation faite, alors qu'avec la tienne, il faudrait la réécrire si je ne m'abuse (enfin, je confonds peut-être avec celle de quelqu'un d'autre, il y en a un certain nombre qui ont été données cheeky).
avatar

1121

Folco:

Je suis de l'avis de KK. Un constructeur doit toujours réussir. L'initialisation d'une classe peut quant à elle échouer. Il faut de plus penser au différents types de constructeur et aux différents types de déclaration (Objet Tableau[3] etc.). C'est d'ailleurs pour cela qu'il faut souvent limiter leur visibilité quand on en a pas besoin.

Tu peux toujours lancer une exception si tu le souhaites de la manière suivante:
Titi toto;
try { 
toto.load(pepe);
} catch(const Titi::exception& e) {
std::cout<<"Prout prout" << e.whatProut() <<std::endl;
}


C'est beaucoup plus simple et parlant que la solution à la barbare. Attention à ne pas deresponsabiliser les classes et remonter au main toutes les exceptions de ton code.
La différence entre une exception et un retour de valeur tiens plus pour moi de la quantité d'information à retourner.

1122

On a une vision assez différente de la chose, c'est marrant. Pour moi une exception doit être lancée quand il n'est pas possible de continuer normalement dans ces conditions. Pour des erreurs normales qui peuvent arriver mieux vaut utiliser la valeur de retour, mais normalement les vérifications devraient être faites en amont, par exemple je préfère:
if (exists("pouet.txt"))
    f = open("pouet.txt");    // exception si le fichier n'existe pas -> ne devrait pas arriver

Plutôt que:
if (!(f = open("pouet.txt")))
    print "Et merde...";    // Le même bordel pour chaque fichier...

La vérification 'exists' n'a pas besoin d'être faite pour des fichiers essentiels de l'application, puisque si un d'eux manque à l'appel l'application ne démarrera simplement pas, et c'est un cas exceptionnel qui mérite de grosses mesures ^^
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

1123

JackosKing (./1103) :
C'est surtout que si le carré derive du rectangle, il doit passer le teste unitaire du rectangle...

trifus c'est encore tes contrats qui ont dit ça?

Dans mon projet actuel, ForStatement et WhileStatement dérivent tous les deux de Statement, mais je vois pas pourquoi les tests sur l'un devraient marcher sur l'autre, ou alors tu testes pas un quart de la vraie fonctionnalité trifus
JackosKing (./1121) :
Un constructeur doit toujours réussir.

je vois pas non plus pourquoi, imagine un FilterInputStream quelconque à qui tu files null à la place d'un stream à lire, pourquoi devrait t on attendre d'appeler une méthode sur le stream parent pour lancer un NullPointerException? encore un contrat?

1124

./1122 > pencil
Pour le reste, je crois que j'ai déjà expliqué mon point de vue, mais je vais en remettre une couche. (Et je pense que ce sera la dernière)
Bug ou erreur dans le déroulement du programme => exception. Toujours.
Ne pas vérifier l'entrée utilisateur est également un bug, donc ça doit lancer une exception. Dans ce cas précis, soit tu as une méthode CheckUserInput, avec un code de retour (à priori un booléen), soit tu interceptes l'exception qui se produit le cas échéant.
Et une dernière chose pour la route: Les exceptions ne doivent pas faire partie du cours d'exécution normal du programme. Et le déroulement normal, c'est les hypothèses que tu as fait sur l'exécution du programme. Par exemple: "le fichier abc.def existe toujours dans le répertoire d'installation" (hypothèse légitime), "l'utilisateur n'entrera jamais de valeur incorrecte" (très mauvaise hypothèse), "Windows est toujours installé dans C:/WINDOWS/" (très mauvaise hypothèse également) ou "La connexion au serveur serveur.vital.com ne doit jamais échouer" (hypothèse légitime).
Le fait que ces évènements ne doivent pas ce produire ne veut pas dire que tu ne dois en aucun cas les gérer, mais après c'est au cas par cas. Il ne faut surtout pas intercepter toutes les exceptions juste pour le plaisir, mais juste celles pour lesquelles ça a du sens. (Sinon tu va contre le principe même des exceptions)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

1125

squalyl (./1123) :
Dans mon projet actuel, ForStatement et WhileStatement dérivent tous les deux de Statement, mais je vois pas pourquoi les tests sur l'un devraient marcher sur l'autre, ou alors tu testes pas un quart de la vraie fonctionnalité trifus
Ce qu’il dit c’est que les tests du Statement doivent réussir quand ils sont réalisés sur une instance de ForStatement ou WhileStatement. Et je pense que c’est effectivement quelque chose d’important à respecter.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

1126

pas convaincu si ça concerne autre chose que les méthodes du parent, mais bon.

1127

Bah on parle bien sûr des méthodes du parent (Statement) vu qu’on parle du test de Statement.
Et c’est super important, si ta classe dérivée de Statement ne respecte pas le contrat de Statement, quand tu l’ajoutes dans ton code, partout où ton code manipule des Statement il peut y avoir des problèmes.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

1128

Pen^2 (./1089) :
Ça ne me parait *pas très* standard

Au contraire, les streams standards font ça grin
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

1129

GoldenCrystal (./1124) :
Ne pas vérifier l'entrée utilisateur est également un bug, donc ça doit lancer une exception. Dans ce cas précis, soit tu as une méthode CheckUserInput, avec un code de retour (à priori un booléen), soit tu interceptes l'exception qui se produit le cas échéant.

Justement à ce sujet je me suis toujours demandé ce qui est le mieux. Si tu as une classe Record avec setInput(...), mon point de vue voudrait que je vérifie que les paramètres puissent jouer avant d'appeler setInput. Ce qui veut dire qu'il devrait y avoir une méthode validateInput(...) dans Record qui permette de savoir si l'input est bonne avant d'appeler setInput.
Le problème avec cette méthode c'est qu'on duplique la vérification, puisque setInput devra le faire de son côté aussi (question de sécurité, ça évite que quelqu'un qui se servirait mal de Record puisse définir des données non-valides).
D'un autre côté la solution avec les exceptions n'est pas terrible. Perso j'ai jamais eu à me soucier de ça puisque je faisais en sorte que les champs ne permettent que des valeurs correctes (via regex & co.), donc si une exception devait survenir c'est que mon code de vérification des champs est faux, donc légitime de s'inquiéter...
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

1130

./1129 > Non, en fait tu n'es pas obligé de dupliquer.
Le modèle à appliquer varie, mais par exemple:
Mettons que tu aies un objet Balle avec une propriété Rayon de type entier.
Donc ton interface doit nécessairement s'assurer que ce que l'utilisateur va entrer pour le rayon de la balle est un entier.
Ensuite, l'objet balle va vérifier les valeurs que tu lui donnes pour modifier le rayon. Tu peux te reposer là dessus et lui passer bêtement l'entier.
Si une exception se produit, alors la valeur n'était pas bonne, donc tu peux l'intercepter et réagir en conséquence. Par exemple en C# tu aurais normalement un ArgumentOutOfRangeException dans ce cas.
En gros là c'est une vérification à deux niveaux. Vérification du type de données, puis validation des informations.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

1131

Ca ressemble fortement à des post-condition pre-condition -> j'aime wink

1132

Design par contrat, j'ai lu WP grin

Ok, merci. En fait, là où je me suis fait baiser, c'est que ma classe de base, Task (la seule instanciée et appelée par main), lançait une classe Module qui ne pouvait pas échouer. Puis Module dérive en StaticModule, qui contient un Plane, des Icon, des StringList etc...
Sauf que Icon peut échouer. Donc Static Module peut échouer à cause d'Icon (et doit l'intercepter). donc Task peut échouer non pas à cause de Module, mais à cause de ce que les dérivés de Module peuvent faire. Or quand j'ai implémenté Task, je savais que Module ne pouvait pas échouer, donc je n'ai prévu aucun mécanisme d'interception. Bossant en top-down, et n'ayant que les classes "du bout" qui peuvent balancer des exceptions, j'ai eu toutes mes classes à reprendre...
Vala, j'ma fait baiser en beauté. smile

1133

Vu que je vous laisse un peu en rade sans question sur laquelle vous battre, en voici une autre (et normalement pas trollesque grin)

Voilà, j'ai des icones... bêtes et méchantes... une taille, des coordonnées, un graphisme "de base", un "cliqué", un "au survol", ça va.
Mais je me rends compte d'un truc... Chaque icone provoque une action différente... Hors si mes icones icones sont toutes de la même classe, comment leur faire appeler une fonction différente à chaque fois ? Coder les 300 méthodes privées à la classe icone pour chacune d'elles et lancer celle kivabien avec icon_truc->execute(icon_truc->get_func_ptr()) ?
Ou alors dériver chaque icone d'une classe icon générique qui a une fonction virtuelle pure Icon::execute() qu'on redéfinit dans chaque classe icone particulière (et là bonjour le nombre de classes sick)

Ca se passe comment dans les softs "ordinaires" et les WM des différents OS ?

1134

Dériver oui
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

1135

Sérieux ? t1 j'ai mal d'avance, je fais un header + un source par classe, ça va chier sévère...
Il y a moyen de rester propre au niveau du code en regroupant les déclarations de classes dans un seul fichier, genre icon_deriv.hpp ?
Ca reste à peu près académique/usuel/lisible/maintenable/etc... ?

1136

Personnellement, plutôt que icon_deriv, qui prendrait un nom lié à un choix technique, je choisirais icons_[groupement fonctionnel/métier/applicatif des icônes].hpp. Mais bon, c'est parce que préfère me placer du côté métier que du côté technique (principalement parce que des années après, on ne se souvient pas forcément de ses choix techniques, mais on doit pouvoir se retrouver au niveau de l'appli dans son aspect métier).
avatar

1137

Donc par exemple, un fichier icon_intro, icon_highscore etc... ? Et grouper les déclarations de toutes les icones intro dans le même fichier, idem pour les implémentations ? Pas mal comme idée, merci. smile

1138

Voilà... c'est un peu ce qui est fait automatiquement quand tu travailles avec un outil de RAD visuel comme VisualBasic (enfin, c'est ce qui était fait il y a 10 ans, mais j'imagine que ça n'a pas trop changé) : ça va créer un fichier par fenêtre affichée, et tous les objets de la fenêtre en question vont se retrouver là-dedans (avec les surcharges de méthodes, etc.).
C'est pas forcément le plus pertinent dans tous les cas, attention, en particulier lorsque tu as des éléments qui peuvent être communs à plusieurs interfaces/processus. Mais bon, là, il y a plusieurs façons d'arbitrer.
avatar

1139

Euh non, normalement ça ne se passe par en dérivant, ça se passe en connectant un signal à un slot!

Sinon, il y a aussi le bon vieux pointeur de fonction, hein.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

1140

La version objet d'un pointeur de fonction étant… tadam… une méthode virtuelle… (Ou un delegate en .NET love )
De toutes façons quelle que soit la méthode utilisée, faut quand même taper tout le code à un endroit ou à un autre donc je vois pas trop le problème tongue
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes