Forum QtFR

La communauté francophone Qt

Vous n'êtes pas identifié(e).

Annonce

Qt 4: 4.8.4 - Qt 5: 5.0.2 - Qt Creator: 2.7.0 - Qt Installer: 1.3.0 - VS Qt 4: 1.1.11 - VS Qt 5: 1.2.1 - Monkey Studio: 1.9.0.4

#1 25-04-2012 19:08:37

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Un exemple client - serveur

beaucoup de gens, quand il doivent réaliser une application client - serveur
attaquent directement le problème en se demandant, par exemple:             
"je veux envoyer ceci, comment fais-je ?"                                   
... puis:                                                                   
"je veux envoyer cela, comment fais-je ?"                                   
...                                                                         

ce qui mène souvent à des solutions dans lesquelles le code est compliqué, difficilement maintenable / évolutif.

tout d'abord, il est souvent utile de disposer de petits de debug simples
exemple: QMap initialisables et à usage de mise au point

dans la suite, le "protocol" désignera le "format des message" pour échange,
par opposition à leur contenu qu'on pourait appeler le "protocole applicatif"

si la première question qu'on se pose est: "de quoi ai-je besoin ?"
la réponse ne doit pas être:                                       
- envoyer mon nom et mon mot de passe --> récupérer et traiter     
- envoyer ... --> récupérer et traiter                             

mais plutôt:
- d'un protocole de transport / échange de données ( n'importe quoi )
- d'un client                                                                     
- d'un serveur                                                                     
- d'un point de connection                                                         
- de quelques définitions communes ( et variables )                               

ceci m'amène à définir une structure globale Tcp dans laquelle tout sera imbriqué:
           
               
l'idée d'imbriquer les structures / classes est de complexifier la structure pour en simplifier l'usage
je dis bien complexifier et non compliquer dans le même sens qu'un nombre qu'un nombre complexe n'est pas un nombre compliqué !

il nous faut définir le protocole.
pour faire simple, disons:       
COMMAND    DATA_SIZE    DATA     
une réponse à une commande pouvant être considérée elle même comme une commande
les classes qui gèreront cela seront:                                         
- Tcp::Buffer                                                                 
- Tcp::Buffer::Input                                                           
- Tcp::Buffer::Output                                                         
                   
       
un intérêt d'avoir la classe Buffer abstraite est d'avoir un seul point pour les modifications communes,
par exemple: QDatasStream::setByteOrder, QDatasStream::setVersion ... tout ce qui doit être "symétrique"

les seuls points de gestion de la cohérence emission / réception sont:
coté Tcp::Buffer::Output                                             
- void init()                                                         
- void send( CmdVal command )                                         
coté Tcp::Buffer::Input                                               
- bool msgRead()                                                     
- CmdVal command;                                                     
- DataSize dataSize;                                                 

pour ce qui est du "support" Socket 3 classes
- Tcp::Socket fournit la gestion de base     
- Tcp::Socket::Client gère emission, réception, exécution coté client
- Tcp::Socket::Server gère emission, réception, exécution coté serveur
                   
                                                                                                                     
on peut constater qu'à ce stade, le traitement de chaque commande est simple                                               
de même qu'il est facile d'en ajouter une nouvelle ou de modifier une qui existe                                           

le point d'entrée, qui est vu de l'exterieur comme le server, que j'appèle Listener car "il ne fait qu'écouter" et créer une Socket qui est le serveur effectif
                     

et enfin !!! un petit test minimum

l'idée de ce sujet n'est pas de fournir
"un truc tout cuit"
encore moins "un truc unviersel" qui conviendrait à tout le monde
encore moins "un modèle de programmation"

mais plutôt de faire sentir que si la finalité est de transporter des données qui nous intéressent,
on peut avoir avantage à attaquer du coté du moyen de transport de ces données sans se soucier d'elles a priori

ou (sic) (Rouletabille) regarder par le bon bout de la lorgnette

Hors ligne

#2 27-04-2012 12:00:07

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

si quelqu'un s'es intéressé au sujet (peut-être suis-je présomptueux)

il aura remarqué que le cas des commandes sans données n'est pas envisagé

la correction est facile

Hors ligne

#3 27-04-2012 13:49:45

dergen
Webmaster Qt
Lieu : Meaux
Inscription : 20-03-2009
Messages : 2 240
Site Web

Re : Un exemple client - serveur

IMPRESSIONNANT !

Excellent travail qui vas aider beaucoup de membres wink


Sans la liberté de blâmer, il n'est point d'éloge flatteur; et qu'il n'y a que les petits hommes qui redoutent les petits écrits !!!

- Beaumarchais -

Hors ligne

#4 27-04-2012 14:55:21

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

Rome ne s'est pas faite en un jour !

recopier dans une nouvelle application un "modèle" existant (source + header),
changer les noms de fichier, les macros de protection des headers, les noms de structures
pour rester cohérent devient vite fastidieux et source d'erreur(s)                       

j'ai donc décidé de faire l'économie de la récuparation transport (struct Tcp::Buffer)

pour cela je l'ai "templatisé" avec pour paramètres:
- CV : type de la valeur de commande               
- DS : type de la valeur data size                 
- S  : type de la Socket associée                   
- NC : valeur indiquant une commande non initialisée

-->
- création de tcptransport.h
- suppression de tcp_buffer.h et tcp_buffer.cpp


les corrections apportées au reste sont minimes:
- tcp.h suppression de la déclaration de Tcp::Buffer (+ une petite réorganisation)
- tcp_socket.h ajout d'un typedef pour acces au nouveau Transport                 


et correction des directives #include

Hors ligne

#5 27-04-2012 15:57:39

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

j'en ai profité pour changer le nom de la structure Tcp --> TcpProtocol

sans rapport avec la modif précedente sinon "logique"
TcpTransport gère le protocole de transport         
TcpProtocol gère le protocole applicatif             

changé aussi les noms de fichier, macros de protection ... pour rester cohérent

travail beaucoup plus long et fastidieux que le précedent !!!

je donne les nouveaux listings en vrac






Hors ligne

#6 27-04-2012 16:58:12

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

pour faire encore l'économie de récupération de tcpprotocol_socket.h et tcpprotocol_socket.cpp,
il me faut rendre les classe Socket dérivables proprement                                     

j'ai besoin que leur méthodes retournent un status, un bool par exemple
pour pouvoir écrire dans une classe fille ClientFille:                 
                                                               
sans avoir à réimplémenter la base           



encore une fois la modif est simple et localisée

pour bien faire les méthodes execute() devraient purement virtuelles pour forcer la réimplementation
purement virtuelles mais implémentée, c'est tout à fait légitime !!!
mais pour mon exemple, ce n'est pas encore possible

Hors ligne

#7 28-04-2012 10:12:53

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

on ne va pas toujours droit au but !

le quatrième paramtre du buffer de transport ne me satisfait pas
je le supprime
j'introduit une gestion par état
- attente de la commande
- attente de la taille des données
- attente des données
je "template" TcpTransport plutôt que TcpTransport::Buffer

une correction à apporter dans tcpprotocol_socket.h ... mais c'est évident !

Hors ligne

#8 29-04-2012 12:31:54

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

roll roll roll certains se sont sans doute demandés:
pourquoi avoir "templaté" la structure TcpTransport, les structures de TcpProtocol n'en utilisent qu'une instance ???

smile smile smile réponse:
pour prévoir la suite

j'avais pensé (quelle présomption !) "templater" de la même façon TcpProtocol, la solution simple

hélas !!!
Q_OBJECT ne supporte pas les classes template, je le savais
mais de plus moc ne supporte pas les classes QObject imbriquées dans une classe template, j'aurais du m'en douter

hiérarchie "imbrication" actuelle des casses de transport:
TcpTransport<CV,DS>                                       
    Buffer                                               
        Input                                             
        Output                                           

hiérarchie "heritage" actuelle des casses de transport:
TcpTransport<CV,DS>                                   
TcpTransport<CV,DS>::Buffer                           
    Input                                             
    Output                                             

je décide
- d'utiliser des fonctions de création d'instance des classes buffer utilisées
- de créer des classes interface non "templatées" organisées comme suit       

hiérarchie "imbrication" des classes interface:
AbsTcpTransport                               
    Buffer                                     
        Input                                 
        Output                                 

hiérarchie "heritage" des classes interface:
AbsTcpTransport                             
AbsTcpTransport::Buffer                     
    Input                                   
    Output                                 

>>>> organisation complète:

hiérarchie "imbrication":
AbsTcpTransport         
    Buffer               
        Input           
        Output           
TcpTransport<CV,DS>     
    Buffer               
        Input           
        Output           

hiérarchie "heritage":
AbsTcpTransport       
    TcpTransport<CV,DS>
AbsTcpTransport::Buffer
    TcpTransport<CV,DS>::Buffer
    Input                     
        TcpTransport<CV,DS>::Buffer::Input
    Output                               
        TcpTransport<CV,DS>::Buffer:Outnput

les modifications de tcptransport.h sont relativement importantes:

tcpprotocol.h se simplifie:       
    suppression des type concernant les commandes et la taille des données
tcpprotoclo.cpp                                                           
    reste inchangé                                                                   


toutes petites modifications dans tcpprotocol_socket.h et tcpprotocol_socket.cpp pour passer les fonctions de création des buffers


toutes petites modifications dans tcpprotocol_listener.h et tcpprotocol_listener.cpp pour passer les fonctions de création des buffers


smile smile smile et enfin le programme de test

Hors ligne

#9 29-04-2012 12:46:36

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

roll roll roll
comment se protéger de l'emploi de deux protocoles de transport incompatibles

(sic)
Pour fabriquer une bombe "A", mes enfants, croyez moi, c'est vraiment de la tarte!
La question du détonateur s'résout en un quart d'heure, c'est de cell' qu'on écarte!

d'accord sur tout, sauf de l'écarter !!!

je vous laisse réfléchir !!!

Hors ligne

#10 29-04-2012 13:15:47

myrddin772
Modérateur Qt
Inscription : 13-03-2010
Messages : 682

Re : Un exemple client - serveur

[curieux=on][mémoire=off]
hmm
Je connais cette citation sur la bombe A... mais plus moyen de situer...
hmm hmm
[memoire=on] wink


"L'informatique n'est pas plus la science des ordinateurs que l'astronomie n'est celle des télescopes." Michael R. Fellows et Ian Parberry
Si tu ne sais pas : demande, si tu sais : partage !

Hors ligne

#11 29-04-2012 13:43:58

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

Boris Vian : La java des bombes atomiques

Mon oncle, infâme bricoleur, fasait en amateur des bombes atomiques.
...

Hors ligne

#12 29-04-2012 13:49:08

myrddin772
Modérateur Qt
Inscription : 13-03-2010
Messages : 682

Re : Un exemple client - serveur

[content=on]
Merci à toi et ta grande culture ! \o/
[content=pas tout à fait off][curieux=off]

Dernière modification par myrddin772 (29-04-2012 13:49:50)


"L'informatique n'est pas plus la science des ordinateurs que l'astronomie n'est celle des télescopes." Michael R. Fellows et Ian Parberry
Si tu ne sais pas : demande, si tu sais : partage !

Hors ligne

#13 29-04-2012 13:56:50

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

myrddin772 a écrit :

[content=pas tout à fait off]

pourquoi ???

myrddin772 a écrit :

Merci à toi et ta grande culture ! \o/

n'éxagérons rien, but, as my sister says, "il y a une chanson pour chaque occasion"
inutile de dire qu'elle chante mieux que moi.

Hors ligne

#14 01-05-2012 23:28:03

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

Nicolas SOUCHON a écrit :
Zanor84 a écrit :

       
Pour ton serveur, utilise tu les thread ?

Sinon un thread règle le problème, voila,

                                 
roll roll roll vachement péremptoire !!! sans avoir vu une ligne de code intéressante

d'une façon générale, les classe de QtNetwork sont asynchrones et ne nécessitent pas de thread

si certains ont essayé l'exemple précédent, ils ont pu constater que tout fonctionnait très bien sans thread

j'aurais pu ajouter: les threads sont "une vaste source d'emmerdements !!!" ... surtout avec les QTcpSocket

explications:
    la création d'une QTcpSocket provoque la création d'un/plusieurs QSocketNotifier
    ce/ces QSocketNotifier doit/doivent "être" dans le même thread que la QTcpSocket
    impossible donc d'utiliser moveToThread avec une QTcpSocket                     

    impossible, par exemple, d'écrire sur la socket sous-jascente à la QTcpSocket depuis un autre thread
    --> communication par signal/slot impérative pour demander à la QTcpSocket d'écrire,               
        pas moyen d'appeler directement ses méthodes                                                   

résultat:
    sad sad sad

smile smile smile mais restons zen:
    tout problème à une solution !!!

j'ai modifié les structures protocole de transport
- pour résoudre ce problème de façon simple
    AbsTcpTransport::Buffer::Output dispose d'un mutex et de methode lock/unlock
    l'émission des données se fait par signal/slot
- pour prévoir des évolutions éventuelles, eg: ajout d'une checksum ...
    les deux buffer travaillent sur un QByteArray interne qui remonte
    de AbsTcpTransport::Buffer::Output dans AbsTcpTransport::Buffer
- j'ai déplacé la structure des fonction de creation des buffers dans AbsTcpTransport::Buffer
    juste pour la logique (perso)

nouvelle structure globale ci-dessous, sources ici chat.gz

Hors ligne

#15 02-05-2012 00:01:54

myrddin772
Modérateur Qt
Inscription : 13-03-2010
Messages : 682

Re : Un exemple client - serveur

Nicolas SOUCHON a écrit :
myrddin772 a écrit :

[content=pas tout à fait off]

pourquoi ???

Parce que les quelques chansons de Vian que je connaisse me font (sou)rire alors, tant que je l'avais en tête, j'etais encore un peu content wink


"L'informatique n'est pas plus la science des ordinateurs que l'astronomie n'est celle des télescopes." Michael R. Fellows et Ian Parberry
Si tu ne sais pas : demande, si tu sais : partage !

Hors ligne

#16 02-05-2012 18:11:57

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

il faut bien par une application: un petit chat par exemple

les structures s'inspireront de TcpProtocol::Listener précédentes, mais n'en hériteront pas, elles ne servaient qu'à la mise au point du principe

organisation des structures:

   Chat // definitions communes
      Listener // écoute (listen) et accepte les connection entrantes, crée threads et serveurs
      Server // le serveur effectif                                                           
         List // liste vérouillable de serveurs                                               
      Client // ça va de soi                                                                   
      Thread // ça va de soi                                                                   
      Widget // prévu pour un avenir "plus ou moins lointain"                                 

roll roll roll questions:
   c'est quoi ce Chat::Widget prévu pour un avenir "plus ou moins lointain" ?

il est vrai que: qui dit chat dit fenêtre à partir de laquelle on peut envoyer et recevoir des messages, mais ...

le principe que jai suivi jusqu'ici est "grosso modo":
   pourquoi se soucier d'afficher les données échangées avant d'avoir le moyen de les échanger ?
   pourquoi se soucier d'échanger des données avant d'avoir le moyen de controler leur transport ?
   pourquoi se soucier d'envoyer des données sur un réseau avant d'avoir un réseau ?             
   smile smile smile heureusement, TCP existe déjà !                                                       
   en bref, pourquoi mettre la charrue avant les boeufs ?

je développe donc, sur la base des classes de TcpProtocol, la partie réseau de mon chat, avec implémentation des threads
je valide le bon fonctionnement ( threads, mutex ...) à coup de qDebug() << ...
c'est souvent beaucoup plus simple que l'utilisation d'un debugger

sources chat1.gz
répartition dans les fichiers


PS: j'allais oublier le petit programme de test

Hors ligne

#17 03-05-2012 13:44:54

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

n'oublions pas que les objectifs
   - dans l'écriture des classes TcpTranport::* est la simplification des classes TcpProtocol::*
   - dans l'écriture des classes TcpProtocol::* est la simplification des classes Xxxx::* (en l'occurence, Xxxx, c'est Chat)

actuellement, il faut
   - (1) réimplementer TcpProtocol::Socket::Client::execute() et  TcpProtocol::Socket::Server::execute() pour pas grand chose

pour ajouter une commande (client -> serveur par exemple), il faut
   - (2) ajouter son nom à l'enum des commandes                   
   - (3) ajouter son nom au mapping de noms pour mise au point   
   - (4) ajouter la méthode d'envoi au client                     
   - (5) ajouter la méthode d'exécution au serveur               
   - (6) ajouter l'appel à la méthode d'exécution dans Xxxx::Server::execute()
   - (7) roll roll roll ce que  j'ai pu oublier             

on peut remarquer que les méthodes d'exécution de commande ont toutes la même signature:
   void execCommand();                                                                 

avec un mapping de fonctions on doit pouvoir faire l'économie du points (1) et subséquemment du point (6)

on commence par valider le principe

modif dans tccprotocol_socket.h

modif dans tccprotocol_socket.cpp

smile smile smile les modifs sont simples
smile smile smile on lance le test et on constate que "tout baigne !"

mais on s'arrête là !
un peu de réflexion avant de tout casser !
je me contente d'appliquer le même traitement à bool TcpProtocol::Socket::Client

Hors ligne

#18 04-05-2012 12:13:55

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

sad sad sad cul de sac !!!
je ne peux pas appliquer la dernière modification pour simplifier comme je le voulais jusqu'au bout

tout au plus je mets en place la même chose dans le client et le serveur du chat
juste pour le plaisir de simplifier le "corps" des méthodes execute()

Hors ligne

#19 04-05-2012 17:46:57

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

un chat !!! il va bien finir par envoyer un message, quand même !!!

OUI !!!

jusque là les commandes échangées étaient simple:
- le client envoie la commande, le serveur l'exécute
ou
- le serveur envoie la commande, le client l'exécute

pour les messages, c'est un peu plus complexe
- le client envoie la commande, du genre MESSAGE TO_LIST MSG_TEXT
- le serveur reçoit, emet un signal
- le listener (qui centralise) envoie une commande du genre MESSAGE FROM MSG_TEXT à tous les clients adressés

on choisit comme convention que TO_LIST vide adressele message à tout les clients connectés

on adapte un peu le petit programme de test

je donne la nouvelle version ci-joint, c'est moins visuel que des extraits de code
mais sans doute plus commode pour ceux que cela intéresse
et de plus ma souris a "la tremblote" et je "pète les plombs" avec les copier/coller

chat sources

notez que : toujours pas d'interface

notez aussi que même si c'est un peu plus complexe, cela se fait quand même assez facilement

Hors ligne

#20 05-05-2012 16:52:37

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

un dernier test avant le gui

pour l'instant, tout fonctionne dans un même process, ça me gêne !

j'adapte un peu la structure de test

et le main

je lance le test, smile smile smile tout baigne !

Hors ligne

#21 06-05-2012 15:35:30

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

les attentifs vont dire : lol lol lol tout baigne, tout baigne, il va un peu vite !

les clients déjà connectés sont informés de l'arrivée d'un nouveau
mais les nouveaux ne savent pas qui est déja connecté

je m'empresse de rectifier le tir :

smile je relance le test, tout a l'air de fonctionner

mad mais une fois de temps en temps un client reçoit deux fois l'information "nouveau client xxxx"

une fois de temps en temps >>>> délicat à diagnostiquer, mais on finit par trouver : le serveur est nommé trop tôt et de plus dans un autre thread
délicat à diagnostiquer, mais correction simple:


smile je relance le test, tout a l'air de fonctionner

Hors ligne

#22 06-05-2012 16:09:20

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

à ce stade, j'introduis dans Chat une structure Chat::Message

implémentation

à la compilation, ça fonctionne
je voulais montrer l'utilisation, mais mes archives ont un petit trou !!!

l'intérêt est que si mes messages évoluent, tout ce qui concernent les prototypes de signaux/slots n'auront pas à changer

Hors ligne

#23 07-05-2012 12:22:29

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

je suis comme beaucoup de gens (sinon tout le monde !) j'ai voulu avoir un résultat tangible trop vite !
l'utilisation de la structure précédente est plus laborieuse que prévue !

pas difficile, mais la circulation d'un message est complexe, elle intervient souvent et il ne faut rien oublier, :
- le client envoie : "un peu de texte" adressé à ... : structure Chat::Message::To
- le serveur reçoit et s'empresse d'ajouter l'origine ; structure Chat::Message::FromTo et "émet" un signal
- le listener demande à tous les serveurs destinataires d'envoyer "un peu de texte"  de ... : structure Chat::Message::From
- les clients reçoivent "un peu de texte"  de ...

dans mes structures, il manquait le passage de Chat::Message::FromTo à Chat::Message::From

je ne montre pas l'utilisation ce serait trop fastidieux à rédiger !!!

la prochaine étape sera un gui minimum !!!

certains impatients diront: lol lol lol Il était temps !!!

Hors ligne

#24 07-05-2012 15:21:08

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

comme tout me semble bien fonctionner je passe à l'étape finale: développement du "gui"

il sera "des plus rustiques" : un petit QWidget composé comme suit:
- un QPlainTextEdit (RO) d'affichage du fil du chat : ChatStreamWidget
- un QPlainTextEdit (RO) d'affichage des autres chatte(u)rs connectés : ChatUsersWidget
- un QWidget de saisie/envoi de message : ChatMessageWidget composé comme suit:
-- QPlainTextEdit (RW) de saisie du message
-- un QPushButton d'envoi
mais permettra de visualiser le bon fonctionnement plus commodément qu'avec les qDebug()


certains remarqueront que je n'utilise pas l'imbrication des structures pour les widgets

la raison en est que le système de feuille de style Qt ne le supporte pas !!!

je joint les sources complets : chat3.gz

Hors ligne

#25 07-05-2012 16:59:02

Nicolas SOUCHON
Administrateur Qt
Inscription : 28-07-2007
Messages : 3 154

Re : Un exemple client - serveur

Point final coté développement !!!
lol lol lol Ouf !!!

C'avait démarré dans les "trucs et astuces"
en "réponse indirecte" à une question posée
et à des trucs tordus ... (à mon humble avis) ... (pas si humble que ça en fait)
et ça s'est transformé en une espèce de tutoriel, d'où le déplacement

Pour clore, quelques petites remarques

Vous l'aurez constaté, je suis un "maniaque de l'alignement"
je trouve que ça participe beaucoup à la lisibilité
vous allez me dire: mais c'est pas aligné !
J'utilise des tabulations à 4 caractères

je mets des commentaires "bizarres"

c'est que j'utilise vim et le folding par la méthode des markers + une "customization" de vim wink @babaOrums

Quelques remarques plus intéressantes

trop de gens ont tendance à réduire C++ à la POO, la structure à l'objet, mais c'est beaucoup plus que cela

- l'imbrication des structures est déjà une forme d'héritage (au sens structurel, pas objet), un petit exemple:

A::Enum est privé à A, mais est accessible directement par A::B

si l'on voulais "sortir B de A, il faudrait
- (1) rendre A::Enum public ou (2) faire de B une classe amie de A
- dans B écrire B() : x( A::V0 ) {}
soit
- une sécurité affaiblie si l'on choisit la solution (1) : A::Enum devient accessible par tout le monde
- une écriture plus compliquée dans le créateur de B

pour ceux qui ont utilisé les classes QDesignerXxxxYyyyZzzzAaaaBbbb, wink imaginez le bonheur potentiel !

- un tout petit bémol lié au signaux/slots de Qt qui fonctionnent avec la chaine de caractère qui nomme un type d'argument
alors que pour une méthode classique j'ai pu écrire par exemple

pour un signal/slot il faut employer le nom de classe complètement préfixé

- le C++ c'est encore la structure vide, magnifique, sublime invention

smile smile smile le namespace c'est bien, le namespace c'est génial
sad sad sad le namespace c'est extensible et je ne veux pas que mon Chat le soit
smile smile smile j'en fais une structure vide au lieu d'un namespace

autre exemple

TcpProtocol gère des commandes :
- HANDSHAKE
- BAD_PROTOCOL
...
des status
SUCCESS
BAD_PROTOCOL // pourquoi le nommer autrement
...
j'introduis des structures vides autour des enums correspondant

et là j'ajoute : je hais le using namespace xxxx;

la structure vide permet de déclarer fonctions locales (pour les nostalgiques de Pascal entre autres)

roll roll roll elle est même instanciable !!!

Il est possible que certaines choses me semblent légales parce que mon compilateur les permet
si quelqu'un a un contre exemple, je suis ouvert à toute remarque

- wink un petit mot à propos de mes amis

on voit un peu partout:
    j'aime pas les 'friend'
    les 'friend' son à proscrire
    ...

je réponds:
    mad mad mad conneries !!!

et je justifie quand même un peu avec un exemple

imaginons une structure

dans certaines circonstances on peut avoir d'un d'un point "restreint", eg: coordonnés d'une case sur un échiquier, ...
on adapte

on veut pouvoir sérialiser, eg: pour pouvoir interrompre une partie puis la reprendre
il nous faut des opérateurs de "streaming" et pour des raisons "techniques"
ils ne peuvent pas être membres de notre classe Point (ils sont évalués de gauche à droite)
on a donc besoin de "friend operators"

il faut considérer que ces opérateurs font partie intégrante de l'interface de la structure Point
et non qu'ils constituent un défaut d'encapsulation

- wink les "setters / getters" c'est bien ... si on en a vraiment besoin !!!

mad mad mad ceci est une connerie (excusez la vulgarité)

ça empêche un code simple

qui doit être remplacé par un autre plus complexe

sans rien gagner : x et y, quoique déclarés privés, sont de fait publiques du fait de l'existence du "setter"

tout ce qui rend l'utilisation finale plus complexe devrait être justifié par un réel besoin !!!

et Qt, me direz vous, quid de tous ses "setters / getters"

Qt en a besoin pour le système des "object's properties", c'est donc (au moins en grande partie) justifié !!!

Hors ligne

Pied de page des forums


Sitemap QtFR