Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Officiels > Programmation > Apprenez à programmer en C++ ! > [Théorie] La Programmation Orientée Objet > TP : La POO en pratique avec ZString > Lecture des commentaires

TP : La POO en pratique avec ZString

Vous devez être inscrit pour pouvoir poster des messages

Page : 1 
Pseudo Commentaire
Page : 1 
Hors ligne MatteX # Posté le 25/03/2008 à 17:28:49 - Ce membre a mis la note : 5
The cake is a lie!
Avatar
Groupe : Membres
Bon choix de TP mais mauvaise utilisation des connaissances. Les opérateurs non pas la forme canonique et l'absence des méthodes constantes fait vraiment une différence pour l'utilisation fluide d'une telle classe.


M@teo21 je dois te taper sur les doigts avec une règle pour le "using namespace" dans un fichier d'en-tête!

liens utiles: FAQ C++ (developpez.com) | GotAPI.com | H-Deb
Mon futur ex-blog | Logique : http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
Propriétaire d'un Dell Inspiron 1720, Core 2 Duo 2.4Ghz, 3Go DDR2, 8600M GT 256Mo. Avec Blu-Ray!
 
En ligne Hertzien' # Posté le 25/03/2008 à 17:44:21 - Ce membre n'a pas mis de note
C++, C(encore)++ fort !
Avatar
Groupe : Membres
Ouuuin je suis pas le premier :p
Très bon TP

19/20 (Because I never give twenty ! (Car je ne donne jamais de vingt !))

Mon problème : [FFMpeg] Installation
Notre équipe : C++ (au complet !)
SuperTux : Le jeu qui innove !
SFML - Anim : Ma classe C++ pour gérer les sprites SFML animés
 
Hors ligne Pole # Posté le 25/03/2008 à 17:49:21 - Ce membre n'a pas mis de note
Chieur professionnel
Avatar
Groupe : Membres
Mouais.
Une fonction pour la concaténation aurait été mieux.
Mais surtout, les fuites de mémoires!
M@teo confond delete et delete[] (le 1er détruit un objet, le 2ème un tableau d'objet!)
 
En ligne M@teo21 # Posté le 25/03/2008 à 18:40:01 - Ce membre n'a pas mis de note
Doh ! Nuts. Mmh, donuts !
Avatar
Admins
Regrettable erreur de ma part pour le delete[], mais j'ai vite corrigé ça :p
Etonnant que ni moi ni les relecteurs ne l'ayons vu !

Mattex > l'absence de const est volontaire car cette notion n'a pas été introduite pour les méthodes à cet instant du cours. Je ne peux donc pas le faire utiliser. En revanche, si tu avais lu attentivement la dernière partie, tu aurais vu que je signale clairement qu'il faudrait passer ces méthodes en constantes une fois que la notion aura été abordée dans la suite du cours ;)

Ce qui se conçoit bien s'énonce clairement,
Et les mots pour le dire arrivent aisément.

Nicolas Boileau (je suis fan)
Suivez l'aventure du SdZ et de Simple IT sur notre blog !
 
Hors ligne shadosan # Posté le 25/03/2008 à 20:35:58 - Ce membre a mis la note : 18
Avatar
Groupe : Membres
ouais, pas mal ^^

et j'ai réussi à faire le ZString en une seconde ! :D

Secret (cliquez pour afficher)
class ZString : public std::string {};


(comment ça, je triche ? non mais ! :lol: )

edit : je viens de finir la classe, avec les suppléments :D
 
Hors ligne MatteX # Posté le 25/03/2008 à 23:24:55 - Ce membre a mis la note : 5
The cake is a lie!
Avatar
Groupe : Membres
@ M@teo21 : C'est pourquoi j'ai dit "l'absence", j'ai bien lu la note de fin.

liens utiles: FAQ C++ (developpez.com) | GotAPI.com | H-Deb
Mon futur ex-blog | Logique : http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
Propriétaire d'un Dell Inspiron 1720, Core 2 Duo 2.4Ghz, 3Go DDR2, 8600M GT 256Mo. Avec Blu-Ray!
 
Hors ligne elmcherqui # Posté le 26/03/2008 à 10:26:57 - Ce membre a mis la note : 20
la vie est un programme
Avatar
Groupe : Membres
tres bon tp . clairement la note maximale .

ps : a quand un tp pour l'heritage et polymorphisme ?

-La répétition est humaine , la récurrence Divine .
 
Hors ligne 0nce # Posté le 26/03/2008 à 11:57:45 - Ce membre a mis la note : 18
Avatar
Groupe : Membres
Très bon tuto, très didactique. Je note 18/20 pour les mêmes raisons que celles évoquées ci-dessus.
 
Hors ligne total chaos # Posté le 26/03/2008 à 12:44:52 - Ce membre n'a pas mis de note
le C++, j'en mange!
Avatar
Groupe : Bannis
j'ai l'impression qu'il y a beacoup de copier coller dans ce tuto, par exmple au lieu de faire ça:
Code : C++ - Afficher / masquer les numéros de ligne
  1. ZString ZString::operator=(const ZString &chaine)
  2. {
  3.     delete[] m_chaine;
  4.     m_chaine = copie(chaine.m_chaine);
  5.     m_longueur = longueur(chaine.m_chaine);
  6.  
  7.     return *this;
  8. }


on peut faire tout simplement:
Code : C++ - Afficher / masquer les numéros de ligne
  1. ZString ZString::operator=(const ZString &chaine)
  2. {
  3.     return operator=(chaine.GetChaine());
  4. }


et ainsi de suite pour les autres operator
 
Hors ligne TheDead Master # Posté le 26/03/2008 à 19:26:38 - Ce membre n'a pas mis de note
4 8 15 16 23 42
Avatar
Groupe : Membres
Me semble qu'il y a une fuite de mémoire ici:

Code : C++ - Afficher / masquer les numéros de ligne
  1. char *ZString::copie(const char *chaine)
  2. {
  3.     int taille = longueur(chaine);
  4.     char *chaineCopie = new char[taille + 1];
  5.  
  6.  
  7.     for (int i = 0 ; i < taille ; i++)
  8.     {
  9.         chaineCopie[i] = chaine[i];
  10.     }
  11.     chaineCopie[taille] = '\0';
  12.  
  13.     return chaineCopie;
  14. }


chaineCopie ne devrait-il pas être libéré ?

Je n'ai plus internet depuis septembre 2008 pour une durée indéterminée.

Comité de lutte contre le langage sms et les fautes volontaires sur Internet.
 
En ligne Nanoc # Posté le 26/03/2008 à 20:11:11 - Ce membre n'a pas mis de note
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Hello,

Premièrement je tiens à dire que c'est une excellente idée que de proposer un TP "technique" à ce stade du cours. J'ai cependant quelques remarques à formuler:

1) Il faudrait préciser quelques part que ZString ne sera jamais aussi bien que std::string malgrès tout le soin que les zéros pourront y apporter. A part dans un but pédagogique, il faut utiliser string qui est bien plus performant et sécurisé que ce qu'un zéro "lamdda" est capable d'écrire.

2) La signature des opérateurs = et + n'est pas correcte. En ce qui concerne +, le mieux serait de le mettre en dehors de la classe et d'utiliser un +=. Cela donnerait les bons réflexes aux lecteurs.

3) Je ne vois pas l'intérêt de la fonction membre "affiche()", puisque tu surcharges << sans l'utiliser.

4) Pouquoi la fonction membre "longueur()" ne renvoit pas simplement la valeur de "m_longueur" (qui devrait être un unsigned int). Ne serait-ce pas plus dans l'esprit "découpage utilisateur/codeur" que de mettre la fonction qui calcule réelement la longueur de "m_chaine" en privé ?

5) Idem pour la fonction "copie" pourquoi ne pas la mettre en privé ?

6) Dans les constructeurs de copie, pourquoi ne pas recopier directement la valeur de "m_longueur" plutôt que de recalculer la longueur de la chaîne ?

7) Pourquoi ne pas utiliser les fonctions "héritées" du C, tel que strlen et strcopy ?

8) Je crois que ça a été déjà dit, mais il y a une fuite de mémoire dans la fonction membre "copie()", la chaîne n'est pas libérée.

Je ne suis plus assez débutant pour pouvoir évaluer ce tuto, mais je pense qu'il est dans l'ensemble assez bon.

Nanoc
 
En ligne M@teo21 # Posté le 27/03/2008 à 17:28:12 - Ce membre n'a pas mis de note
Doh ! Nuts. Mmh, donuts !
Avatar
Admins
J'ai déjà répondu à la plupart de ces remarques en commentaire de news.

Pour la fonction de copie, ce n'est pas une erreur, elle n'est là que pour copier la chaîne et non pas pour supprimer celle qui lui est passée en paramètre. Il n'y aura pas de fuite de mémoire si l'utilisateur de la classe supprime lui-même la chaîne, ce qui se fait automatiquement quand on utilise des guillemets "".

Ce qui se conçoit bien s'énonce clairement,
Et les mots pour le dire arrivent aisément.

Nicolas Boileau (je suis fan)
Suivez l'aventure du SdZ et de Simple IT sur notre blog !
 
Hors ligne mostlaab # Posté le 28/03/2008 à 20:04:17 - Ce membre n'a pas mis de note
toujours chercher pour savoir
Groupe : Membres
merci, très bien, pour le grand tuto bien pratique et surtout pour le temps consacré .
la note maximale en découle , trés bien mérité.
Citation : Mateo21
J'ai déjà répondu à la plupart de ces remarques en commentaire de news.

je propose le lien :
commentaires de news
Hors ligne Thomthom # Posté le 29/03/2008 à 21:16:27 - Ce membre a mis la note : 19
ga habs go
Avatar
Groupe : Membres
je ne donnerai jamais de notes parfaites, toutefois... c'est un EXCELLENT tp... Mais j'ai seulement une question: Quelle est l'utilité de faire trois méthodes rechercher()? Il me semble qu'on pourrait très bien utiliser celle de la chaine de caractères (recherche(char*)) pour ne rechercher qu'un seul caractère, non?

Code : PHP
1
<?php $pays = "QUÉBEC"; $statut = "independant";?>
 
Hors ligne 008 # Posté le 30/03/2008 à 01:49:47 - Ce membre a mis la note : 20
Groupe : Membres
supprimer

J'espère avoir été clair :p si besoin plus d'information dites-moi le :p
:D Merci d'avance :D

La doc a toujours raison

Merci Pour vos futur réponse
 
Hors ligne 008 # Posté le 31/03/2008 à 03:32:08 - Ce membre a mis la note : 20
Groupe : Membres
supprimer

J'espère avoir été clair :p si besoin plus d'information dites-moi le :p
:D Merci d'avance :D

La doc a toujours raison

Merci Pour vos futur réponse
 
Hors ligne lmghs # Posté le 31/03/2008 à 21:43:00 - Ce membre n'a pas mis de note
Groupe : Membres
Hé hé. Je viens de comprendre d'où venaient toutes ces ZString et autres questions sur les opérateurs dans le forum.

Des petites remarques au fil de la lecture

a- Ca serait vachement bien de ne pas entretenir les gens qui incluent <iostream> à tout bout de champs. <iostream>, c'est pour les 4 flux globaux.
Pour déclarer dans les .h, c'est <iosfwd>.
Pour définir (!=déclarer) les 2 opérateurs d'extraction et d'injection, c'est respectivement <istream> et <ostream>

<iostream> n'est pas un en-tête magique qu'il faut mettre partout, les temps de compilation sont déjà assez longs comme ça.


Et surtout, pas de using dans un .h ! Encore moins le using std.



b- Une longueur de chaine ne peut pas être négative. Autant utiliser size_t (ou un nom approchant)


c- "quelle que soit la classe qu'on écrit, il est toujours conseillé d'écrire le constructeur de copie "
C'est faux. Seulement si il y a des données membres qui sont en fait des ressources brutes dont la classe est responsable -- comme c'est le cas ici. Ou si on veut/doit interdire pour raison de sémantique d'entité.


d- Bien que le destructeur ne soit pas virtuel! (même si le chapitre correspondant n'a pas été vu)


e- Les deux utilisations du constructeur d'initialisation/conversion ne sont pas identiques. L'utilisation avec "=" n'est pas possible si le constructeur est déclaré "explicit"


f- Hum ... Ne pas utiliser strlen est un mauvais conseil. Le syndrome du NIH est une source interminable de problèmes, une vraie plaie. Dans un tuto sur la réécriture de la lib C, je ne dis pas. Dans un tuto sur l'écriture d'une classe de chaine, il y a déjà bien assez à faire, non ?
Surtout si c'est pour donner les deux fonctions avec un "voilà, c'est comme ça et ça marche".
Au final ils risquent juste de retenir qu'il faut réimplémenter la libc parce qu'ils font du C++.
Apprendre à bâtir à partir de l'existant est également important.


g- Très bien de s'attarder sur le partage, et qu'il faille impérativement dupliquer.
(Même s'il est faux de dire que la constante litérale "Bonjour" puisse être supprimée :euh: )


h- Le constructeur d'initialisation/conversion appelle deux fois le calcul de longueur. La solution efficace est d'appeler strlen, puis de faire tout simplement un memcpy (par construction (comme on dit en maths) la chaine source est zéro-terminée, et on connait la longueur des deux tableaux)
Même remarque pour la copie.


i- A un moment donné, tu parles de l'inadéquation de la liste d'initialisation. Tu n'y es pas revenu comme promis (j'ai fais une recherche sur "liste"), et je ne vois pas en quoi ce n'est pas utilisable ici.
Code : C++ - Afficher / masquer les numéros de ligne
  1. struct Chaine {
  2.     Chaine(char const* s = "")
  3.     :m_longueur(strlen(s))
  4.     ,m_tampon (new char[m_longueur+1])
  5.     { memcpy(m_tampon, s, m_longueur+1); }
  6. private: // l'ordre de déclaration est très important ...
  7.     size_t m_longueur; // déclaré d'abord
  8.     char * m_tampon; // déclaré après
  9. };

(Les optimisations se voient toujours dans un second temps. Donc dans un second temps : l'empty strings optimization, et dans un troisième : la small strings optimization.


k- Même si la syntaxe de l'opérateur d'injection est barbare, elle n'est pas compliquée au point de devoir lier la classe à une donnée globale qui est std::cout. Toujours décorréler l'affichage du métier. Il ne faut pas leur donner de mauvaise habitudes.


l- s/combiner/concaténer/


m- Vu que le constructeur d'init/conversion n'est pas explicit, inutile de surcharger deux fois l'opérateur d'affectation. Le seul gain est de type optimisation. Et comme chacun le sait, cela peut être vu dans un second temps. Et encore, il y a moyen de gratter bien plus sur du vrai code -- cf les concatenators qui squattent illégalement la std::string de la STLPort.


n- L'opérateur d'affectation ne doit pas renvoyer de copie, mais une référence sur *this


o- Non. L'opérateur d'affectation bosse à l'envers
Toujours allouer avant de libérer -- en passant par un temporaire bien évidemment

(Bon, c'est bien de ne pas être tombé dans le piège du test visant à contrer l'auto affectation.)
Eventuellement, il y a la feinte du swap qui s'applique ici.


p- Comme dit plus haut, il manque les const pour les opérateurs -- et ailleurs.
(Et je ne démordrais pas qu'il faut commencer par montrer les bonnes pratiques, car ce code, des zéros sont capables de le copier-coller dans du code industriel :( )


q- J'en avais parlé dans mes précédentes critiques au sujet des opérateurs, cette forme d'opérateur binaire membre est non idiomatique et serait mieux à être passée sous silence.


r- L'information comme quoi cela n'a pas marché du premier coup ne fait que valider le fait que le syndrome du NIH, c'est mal :P

s- De nouveau de la duplication de code (on entre limite dans le non respect du DRY cette fois ^^ ) pour l'opérateur de concaténation.

t- copie() devrait être statique. Mais str(n)cpy est bien aussi. :P



Soit des pinaillages comme d'hab'. Même si certains méritent fortement d'être pris en compte.
Sinon bonne initiative. Très bien de montrer une classe à sémantique de valeur qui est responsable d'une ressource brute. C'est un des cas d'école qu'il est important de maitriser.
 
Hors ligne 008 # Posté le 01/04/2008 à 23:11:38 - Ce membre a mis la note : 20
Groupe : Membres
Est-ce que quelqu'un pourait me donner le code pour les 3 methodes recherche




merdi d'avance :p :p :p

J'espère avoir été clair :p si besoin plus d'information dites-moi le :p
:D Merci d'avance :D

La doc a toujours raison

Merci Pour vos futur réponse
 
Hors ligne angelsafrania # Posté le 03/04/2008 à 16:09:54 - Ce membre n'a pas mis de note
623
Avatar
Groupe : Membres
Il n'y a pas le principe d'amitié dans le code pour les opérateur c'est bien dommage ça peux évité d'avoir plein de fonction annexe

Projet Actuel :
Faire le site perso le plus vite possible en XML/XSLT compatible mobile + modularité formidable (enfin des trucs de rêve)
 
Hors ligne lmghs # Posté le 03/04/2008 à 18:27:13 - Ce membre n'a pas mis de note
Groupe : Membres
@angelsafrania: Nous sommes dans un cas où l'amitié n'apporte rien. De plus ces fonctions que tu dis "annexes" ne le sont pas vraiment. Elles deviennent nécessaires quand on veut interfacer cette classe, ZString, avec des API façon C de manipulation de chaines de caractères.
 
Hors ligne zoro_2009 # Posté le 24/04/2008 à 22:14:36 - Ce membre n'a pas mis de note
Avatar
Groupe : Membres
Citation : Mateo dans un chapitre précédent
Dans les .h, il est recommandé de ne jamais mettre la directive using namespace std; car cela pourrait avoir des effets néfastes lorsque vous utiliserez la classe par la suite.
Par conséquent, il faut rajouter le préfixe "std::" devant chaque string du .h. Sinon, le compilateur vous sortira une erreur du type "string does not name a type".


Citation : Mateo dans ce chapitre
Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#ifndef DEF_ZSTRING
#define DEF_ZSTRING
 
#include <iostream>
 
using namespace std;
 
class ZString
{
    public:
 
    private:
 
};
 
#endif

"Si vous ne pouvez pas expliquer un concept à un enfant de six ans, c’est que vous ne le comprenez pas complètement"
Albert Einstein
 
Hors ligne Heliane # Posté le 14/05/2008 à 15:23:47 - Ce membre a mis la note : 17
Groupe : Bannis
Bonjour.

Il est chouette ce tuto, mais il semblerait qu'à la première déclaration de *m_chaine tu aies oublié l'underscore (ce qui donne *m chaine au lieu de *m_chaine)...

Voilà bonne continuation!
Hors ligne funduk # Posté le 23/06/2008 à 21:12:00 - Ce membre a mis la note : 18
Avatar
Groupe : Membres
T.P. très interessant M@teo !
OOOOHHH, mais que vois-je, une faute d'orthographe du Maître de la Cave ??? :D
Citation : M@teo 21
Comme on l'a vu dans un des chapitres précédents, il faut copier la chaîne (en appelant une fonction de copie que l'on écrirera) et faire pointer m_chaine vers cette copie.
Dans Constructeurs et destructeur / Le constructeur ZString(const char *).
18 parce que j'ai beaucoup aimé le sujet.

┗┫━━ ┃ ━━ ┣┛ ┣┫
 ┃ ━━━━━  ┃┏┳┫┣┳┓ 
 ┗━━┳━┳━━┛ ┃    ┃ 
━━━━┃ ┃    ┗━┳┳━┛
( :p )
 
Hors ligne zerolotfi # Posté le 22/07/2008 à 01:11:28 - Ce membre n'a pas mis de note
Groupe : Membres
Félicitations M@téo génial ton cour,

Une petite question pour le TP ZString si tu permets:

La surcharge de l'opérateur '=' grâce à: ZString operator=(const ZString &chaine);

C'est pour pouvoir faire: chaine1 = chaine2;

Mais est ce que le constructeur de copie: ZString(const ZString &chaine);

ne le fait pas déjà?
Hors ligne nath # Posté le 24/07/2008 à 15:41:36 - Ce membre a mis la note : 19
yeeah, rastafari!!!!
Avatar
Groupe : Membres
Bonjour, très bon tuto :) ,

en tant que débutant je me demandais pourquoi tu avais écrit cela (voir le commentaire):

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
ZString ZString::operator+(const char *chaine)
{
    int tailleTotale = m_longueur + longueur(chaine);
    char *sommeChaines = new char[tailleTotale + 1];
 
    for (int i = 0 ; i < longueur(m_chaine) ; i++)//ici pourquoi ne pas mettre plutôt m_longueur à la place de longueur(m_chaine) ?
    {
        sommeChaines[i] = m_chaine[i];
    }
 
    for (int i = m_longueur ; i < tailleTotale ; i++)
    {
        sommeChaines[i] = chaine[i - m_longueur];
    }
    sommeChaines[tailleTotale] = 'anti-slash0';
 
    ZString resultat(sommeChaines);
    delete[] sommeChaines;
    return resultat;
}


De plus il me semble qu'écrire ceci fait que la fonction sera appelée à chaque fois que ça bouclera (en tout cas il me semble que c'est comme ça en PHP :-° )

Voilà, pas très important mais bon ^^

Sinon, merci pour ce bon tuto (comme pour les autres) :)
 
Hors ligne valpokbest # Posté le 09/09/2008 à 19:46:19 - Ce membre n'a pas mis de note
Voltaire a dit un jour:
Avatar
Groupe : Membres
Je ne mettrai pas de note étant très mauvais juge :p
Mais je poste simplement pour un petit truc intéressant :
J'avais juste mis le prototype :
Code : C++
1
ZString operator=(const char *chaine);

dans ZString.h et la fonction :
Code : C++
1
2
3
4
ZString ZString::operator=(const char *chaine)
{
    
}
dans ZString.cpp
et dans mon main.cpp:
Code : C++
1
2
3
4
5
6
ZString chaine("Bonjour"), autreChaine;
    chaine = "Salut";
    autreChaine = chaine;
    chaine.afficher();
    autreChaine.afficher();
    return 0;

Et qu'avais-je? o_O
Code : Console
Bonjour
Bonjour

Pourquoi le deuxième bonjour était-il affiché??? o_O
Là je reste sceptique... Pourquoi écrire la fonction si ça marchait déjà avant? :p

Sur ce bon tutoriel quand même, intéressant.
J'aime mieux quand on est suivi tout le long moi qui ne suis pas trop débrouillard pour l'instant xD

http://pokestyle.com | RPG ONLINE enfin disponible! Fans de pokémon? Venez
Ubuntu 9.04 The Jaunty Jackalope (la jackalope enjouée). Mais savez-vous ce qu'est une jackalope? Et bien comme le dit http://doc.ubuntu-fr.org/ , "la jackalope est un animal imaginaire entre la chèvre et l'antilope"! Les programmeurs ont encore du absorber une trop grosse dose de 0 et de 1...
 
Hors ligne reckahomis1 # Posté le 14/09/2008 à 04:44:19 - Ce membre n'a pas mis de note
E=mc² et le soleil tourne
Avatar
Groupe : Membres
franchement c'est un super tuto et trés utile,
mais pour moi et sans mensenge, je me suis trompé dans la derniere partie : surcharge des operateurs
bouceaup des methodes, ont le même principe, ce qui manque est qu'il n'est pa indiqué quand on a le droit d'utiliser chaqu'une de ces methodes-là.
Comme un debutant en POO, ca ce que je vois. et il faut que je relirai ce tuto une autre fois pour le metriser.

en tout cas merci Mateo, a la prochaine
Hors ligne djmcg # Posté le 05/11/2008 à 16:01:09 - Ce membre n'a pas mis de note
Pour avancer, il faut savoir a
Groupe : Membres
Là, je doit relire encore, je suis largué.
Ces fort cette classe ZString, j'ai l'impression que l'on peux faire presque n'importe quoi avec ce langage.
Tu juste qu'à inventer ce que tu a besoin....
ouf'ti :p

Jean-Marie Dubasik
 

Vous devez être inscrit pour pouvoir poster des messages

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 284 Zéros connectés | Requêtes SQL 9 requêtes | Temps de génération de la page : Total (SQL) 0.0402s (0.0273s)