30

polar-bear-cafe-penguin.jpg
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

31

lol grin

32

mouarf grin

33

Dans le projet sur lequel j'ai bossé un peu plus de 3 ans à plein temps au boulot, qui doit s'interfacer avec beaucoup de choses qui ne sont pas Qt, on a clairement trop utilisé Qt. Le logging utilisé partout serait beaucoup plus efficace sans Log4Qt (et encore, on utilise les QStringLiteral de Qt 5, après amélioration du code de Log4Qt, contribuée à upstream et intégrée), et certaines parties qui ne font pas de présentation utilisent trop largement les strings Qt.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

34

Ok merci pour ce feedback. Est-ce que tu peux juger si ça s'applique aussi à un petit projet perso, ou si c'est une prise de tête à éviter ?
Ah, et dans la mesure du possible, je veux éviter autant que faise se peut la STL, et tant pis pour std::exception, je lui préfère mon wrapper de QString. langue

35

Mon avis personnel est qu'on ne peut pas trop utiliser Qt, seulement trop peu. Pour les bibliothèques tierces, la solution est de faire un binding Qt par dessus (comme le sont par exemple QtGStreamer ou Phonon pour GStreamer, ça montre aussi les 2 approches: bindings bas niveau ou couche d'abstraction).
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é

36

Pour un petit projet perso qui tourne sur un puissant x86_64, peut-être de façon intermittente, et développé sur un temps libre précieux, je dirais que ce n'est pas très grave.

Pour ce qui serait censé devenir un jour un produit tournant 24/7 sur des x86_64, mais aussi sur des plate-formes embarquées plus limitées et beaucoup plus économes en énergie (ARMv7 < 1 GHz, éventuellement < 512 MB de RAM; on n'est clairement pas dans de l'embarqué obsolète type calculatrices ou encore plus limité, mais il faut quand même se préoccuper ne pas se vautrer comme un gros sale), non évolutives et avec une assez longue durée de vie... c'est quand même bête de charger la machine à faire un taux énorme d'allocations / libérations mémoire avec des objets de trop haut niveau (plus haut niveau que nécessaire), dont les conversions de strings.

Si c'est pour obtenir des données depuis une source de strings C, les traiter, puis les stocker ou diffuser sous forme de strings C ou de std::string (mais certainement pas de QString), il est stupide, parce que très inefficace, de convertir (const) char * -> QString -> char *: en gros, ça se traduit en allocation mémoire + exécution du constructeur + conversion vers UTF-16 + conversion depuis UTF-16 + exécution du destructeur + libération mémoire. Je passe sur le refcounting.
On a évité cet anti-pattern évident dans la plupart des parties de code (par exemple, dans les outils de production, nous avons à raison banni le parsing de JSON et de XML avec une quelconque librairie basée sur Qt)... sauf pour le logging. On n'a pas vu tout de suite à quel point le code basé sur Log4Qt est inefficace. Une fois qu'on a mis du logging en QString explicite quelque part (QString::format, par exemple), il faut réécrire le code - si on a le temps, bien sûr...


Tu hurlerais au fou si sur TI-68k, qui est un contexte très différent, quelqu'un faisait un truc aussi gros et aussi lent que la conversion (const) char * -> QString -> char *, Folco wink


Une autre façon de trop utiliser Qt, dans certains contextes tout à fait légitimes, est d'utiliser à outrance les signaux/slots. Qui dit signaux et slots, dit moc, donc méta-données contenant des noms en clair (surtout en Qt 4) et facilitant le reverse-engineering de l'application même en la complète absence d'infos de debug.


Ah, et puis un argument, beaucoup plus faible il est vrai: le temps de compilation. Si tu inclus <QObject>, tu tires plus de 50K lignes de headers C++ (j'ai regardé pour la dernière fois avec un Qt 5.3, je dirais). Si tu inclus par flemme <QtCore>, qui tire des dizaines de headers, c'est pire. En plusieurs étapes sur quelques mois, j'ai réduit le temps de build de la partie principale du projet de ~4m10s vers ~2m40s, alors que l'application grossissait entretemps. Une des étapes significatives de l'optimisation était de ne pas inclure <QtCore> à tout va, et de ne pas inclure <QObject> dans les headers de plus haut niveau.


Comme beaucoup de choses en informatique et dans la vie de tous les jours: Qt, c'est bien, mais point trop n'en faut.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

37

Les signaux et slots sont mieux maintenant, quand même.

38

Quand on peut utiliser la nouvelle syntaxe, oui. Je n'ai pas réussi à faire ça partout dans la base de code du boulot lors du passage Qt 4 -> Qt 5, notamment en présence de slots virtuels dans l'interface, redéfinis avec une vraie implémentation par les classes filles.

Si la future réflexivité C++ est suffisamment puissante, Qt essayera de l'utiliser. Mais il est encore bien trop tôt pour pouvoir l'utiliser de manière inconditionnelle, ça prendra des années - voir le fait qu'il n'y ait toujours pas de version de Qt qui utilise de façon inconditionnelle les features modernes du C++11.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

39

Les pointeurs de méthodes en C++ ne gèrent-ils pas automatiquement les méthodes virtuelles? Sinon, tu peux aussi utiliser une méthode privée, voire un lamda, qui appelle la méthode virtuelle.
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é

40

Bon, voici ce que j'ai mis en place :
- la partie Interface fait une demande de nouveau vélo à Application
- Application demande à Données de lui fournir un objet VeloSpec, qui fournit les valeurs min, max et défaut qui nous intéressent
- Application pop le dialogue de création de vélo avec pour argument le VeloSpec

La classe VeloSpec ne fournit que des getters. Ca peut aussi bien être utilisé dans le cas au-dessus, que directement par Interface si l'envie lui prend d'afficher des renseignements divers, que lors de l'ouverture d'un fichier, pour vérifier la concordance des données.

(bon, je sais pas pourquoi, mais ça me parait tout couillon comme solution, à se demander pourquoi je me posais des questions. A moins que ce soit très nul, peut-être ? cheeky)

41

Bon, et ben j'ai fait encore plus fun.

Soit mes 4 classes du moment :
- Vélo
- VéloData
- EditVélo
- AfficheVélo

Le problème à résoudre : Editer, afficher et enregistrer des données, sans que n'importe quelle classe trifouille dans les données, ni dupliquer les données pour les dispatcher ici et là.

Et c'est fichu comme ça :
- VéloData est une classe qui ne fait rien à part contenir des données et des getters. L'initialisation des membres se fait par le constructeur, la modification par une classe amie
- VéloData est amie de Vélo
- Vélo possède un exemplaire de VéloData dans ses membres privés, donc peut bosser sur ses données sans souci
- EditVélo et AfficheVélo reçoivent un VéloData* pour bosser, et peuvent donc lire et non modifier les données.

Contrat rempli. smile

Moi qui prenant [fixed]friend[/friend] pour le mal absolu et ne l'avais jamais utilisé, ça me permet ici de me sortir élégament de cette situation. Enfin, je crois trigic
Call : Zeph appelé(e) sur ce topic...

Tu trouves ça si crade que ça ?

42

Oui, juste à cause de la solution et sans avoir eu besoin de lire tes deux posts grin

Je regarderai ça demain ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

43

Dans ce cas, au lieu de travailler avec friend, je ferais soit une seule classe Velo, où les méthodes en lecture seule sont const et où EditVelo et AfficheVelo reçoivent un const Velo *, soit je changerais VeloDataVeloInterface et ferais hériter Velo de VeloInterface.
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é

44

Zeph -> je te fais grâce de l'avant dernier. C'est toujours d'actualité, mais c'est pas en rapport avec le post suivant.

Kevin -> Ah, bien pensé. AfficheVelo et EditVelo peuvent reçoivent un const VeloInterface*, c'est ça ? Bonne solution, j'avais pas pensé à utiliser de cette façon l'héritage et le constness, c'est superbe, merci beaucoup. top

(et hop, reparti pour une troisième refactoring, j'adore ça faut croire magic)

edit -> c'est marrant d'utiliser la dérivation pour ça quand même, parce qu'un Vélo possède des données, plus qu'il n'est une interface. M'enfin, ça marche parfaitement quand même.

45

const VeloInterface * combine mes 2 idées, c'est possible. Probablement pas absolument nécessaire (soit les const, soit l'interface, devraient suffir), mais c'est probablement le plus propre.
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é

46

Si les membres données de VeloInterface sont seulement protected, ça permet d'y accéder directement dans Velo, sans rien exposer pour les autres classes ? C'est pas trop crade, Zeph ? cheeky

47

(J'ai pas lu en détail mais les héritages artificiels -- si c'en est bien un, je trouve ça ignoble grin)

48

Bah, c'est le pattern interface, le C++ ne distingue pas entre classe/héritage et interface/implémentation.
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é

49

Edit cross
Bonn so kneel burn colitis
Tiens mon clavier est passé en anglais #trihum#
Bref embarrassed

En fait je vois mal le rôle de vélo par rapport à velodata et éditvelo. Vélodata contient juste les données, OK, mais quel sont les rôles de vélo et editvélo ?
Vélo data est une version readonly de vélo ?

50

Kevin > Ah oui OK si c'est une interface c'est différent, évidemment.

51

Velo, c'est un vélo dans toute sa splendeur, on peut modifier sa couleur, changer son dérailleur ou sa selle. Ca joue sur les données, donc.
EditVélo, c'est le dialogue qui permet d'éditer les données.
AfficheVélo, c'est ce qui atterrit sur la fenêtre principale, et qui permet de savoir de quoi on parle.

52

Pen^2 (./50) :
Kevin > Ah oui OK si c'est une interface c'est différent, évidemment.
Il faut dire qu'en C++ tout peut être un peu plus flou parce que justement le langage ne distingue pas, donc on peut avoir des interfaces avec du code (mais bon, la dernière spécification du Java le permet aussi, cf. "méthodes par défaut"), et ce ne sont même pas forcément des classes abstraites (mais devraient l'être, instancier une interface est toujours une erreur).
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é

53

pour moi, la modification des données doit se faire par des méthodes (des setter, ou équivalent) de velodata. affichevelo et editvelo doivent être essentiellement des boîtes de dialogue avec des slots pour répondre aux signaux qui se contentent d'utiliser les setter de velodata.
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

54

et en cas d'entrée invalide, il est censé faire quoi le setter ?
en tout cas, affiche velo n'a pas besoin de setters dans velodata. C'est plutôt editvelo qui a le cul entre deux chaises.

Pour info, Qt semble proposer un mécanisme de délégation pour ça, mais je connais pas trop le principe. Peut-être est-ce en rapport avec les delegate du C dièse ? (embarrassed)
http://doc.qt.io/qt-5/model-view-programming.html
modelview-overview.png
L'image ne m'inspire pas en tout cas.

55

1) lever une exception ^^
2) oui, mais si dans la liste avec tous les vélos, tu veux modifier un nom directement ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

56

1) autant ne rien faire, renvoyer faux si le setter refuse l'édition proposée, auquel cas l'éditeur ne valide pas l'édition en cours (il peut s'agir d'une lettre tapée ou de l'incrément d'une valeur)
2) c'est là que Qt propose son espèce de délégate, non ? pour moi le problème posé est le même qu'au 1, non ?

57

L'exception est pourtant la solution la plus propre pour ton point 1.
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é

58

J'ai du mal à voir en quoi. renvoyer une exception pour dire non, ou false, quel différence ?

59

Si tu oublies de catcher ton exception, tu le sais tout de suite (et avec un compilateur supérieur si tu ne catches ou délègue pas à l'appelant, ça ne compile même pas). Le code d'erreur, tu peux oublier de le lire.
Et de toute façon une exception est beaucoup moins pénible à gérer.(et ça libère le valeur de retour pour un truc utile)
(Pas le temps de répondre au reste pour l'instant, et puis surtout sur téléphone c'est pénible grin)

60

oué bref, tout ça c'est des détail d'implémentation, ça a pas grand chose à voir avec le probème initial en fait.