IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Template, et operateur surchargés !


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Par défaut Template, et operateur surchargés !
    Bonjour !

    Alors j'ai 2 petits problèmes, le premier, au niveau de l'écriture d'un template:

    Avant j'avais dans ma classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	int GetHeader();
    	int GetAction();
    	int ReadInt();
    	long ReadLong();
    	std::string ReadString();
    Et en passant sur le chapitre templates de mon bouquin, je me suis dis que je devais changer ca !

    Ma classe:
    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
     
    class Packet {
    private:
    	int index;
    	queue<byte> *bytes;
    public:
    	Packet();
    	Packet(char &s);
    	~Packet();
    	template<typename T>void read(T &buf);
    	void Next();
    	Packet& operator+(long l);
    	Packet& operator+(int i);
    	Packet& operator+(char *s);
    	Packet& operator+(byte b);
     };
     
    int substr(char *s, int start, int length);
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    Packet::~Packet() {
    	//delete this;
    }
    Packet::Packet() {
    }
    Packet::Packet(char &s) {
    	bytes = new queue<byte>;
    	int len = strlen(&s);
    	cout << &s << endl;
    	int _bytes = floor((float)len/2)-floor((float)len/6);
    	for(int i=1; i<=_bytes; ++i) {
    		bytes->push(substr(&s, (i-1)*3, 1));
    	}
    }
    void Packet::Next() {
    	++index;
    }
    template<typename T>void Packet::read(T &buf) {
    	cout << "size of argument: " << sizeof(T) << endl;
    }
    Packet& Packet::operator+(long l) {
    	return *this;
    }
    Packet& Packet::operator+(int i) {
    	return *this;
    }
    Packet& Packet::operator+(char *s) {
    	for(int i = 0; i < strlen(s); ++i) {
    		bytes->push(s[i]);
    	}
    	return *this;
    }
    Packet& Packet::operator+(byte b) {
    	bytes->push(b);
    	return *this;
    }
    int substr(char *s, int start, int length) {
    	char t[2] = {s[start], s[(start+length)]};
    	return (int)strtol(t, NULL, 16);
    }
    J'aimerais pouvoir faire par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	char *p = "01 02 05 6b 6b 6b 6b 6b ff aa";
    	Packet *pk = new Packet(*p);
    	int h, a, l;
    	long v;
    	char *str;
    	pk->read(h); // h = 01 - readint
    	pk->read(a); // a = 02 - readint
    	pk->read(str); // str = 6b 6b 6b 6b 6b  (en prenant en compte de lire le 05 = length du str)
    	pk->read(v); // v = aa ff
    Voila,
    le deuxième problème est au niveau de la surcharge d'operateurs

    J'ai un thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DWORD WINAPI ls_Listen(LPVOID para) {
    	XServer::LoginServer *ls = (XServer::LoginServer *) para;
    //[.......]
    Plus bas, j'accepte un socket et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    							Client *c = new Client((std::string)inet_ntoa(csin.sin_addr), (int)ntohs(csin.sin_port), csock);
    							ls += c;
    Donc je creer mon object client, en donnant toutes les valeurs (tout va bien)
    VC2010 me dit que 'c' doit avoir un type integral ou enum ?!

    La déclaration de LoginServer operator+:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    XServer::LoginServer& XServer::LoginServer::operator+(Client &c) {
    	Clients += c;
    	return *this;
    }

    La déclaration de Clients operator+:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Sessions& Sessions::operator+(Client &c) {
    	clients[c.Get()->_aid] = &c;
    	return *this;
    }
    Comment faire pour corriger cette erreur?

    Merci d'avance, nico

  2. #2
    Membre expérimenté Avatar de Kazh Du
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 152
    Par défaut
    Je ne comprends pas ton premier problème, qu'est-ce qui ne fonctionne pas ? (je n'ai pas de compilateur c++ avec moi, je ne peux pas tester)

    pour ton 2eme problème :
    lorsque tu fais "ls += c;", tu additionnes 2 pointeurs ! La syntaxe correcte serait :
    Ensuite, l'opérateur += n'a pas été défini.
    Enfin, je dois avouer que je ne comprends pas pourquoi tu utilises l'opérateur +, à mes yeux ça ne veut pas dire grand chose. Mieux vaut utiliser une méthode addClient(Client &c) qui a plus de sens. Surtout que la syntaxe correcte d'un opérateur + devrait ressembler à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class1& class1::operator+(const class2 &c) const;
    car elle ne devrait modifier aucun paramètre mais créer un nouvel objet.

  3. #3
    Membre très actif
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Par défaut
    Bojour,

    Pour mon Premier probleme, jessayer de simplifier toutes mess methodes readint readlong readstring en une seule methode, et je crois quil faut les templates pour ca!

    Pour le deuxieme, je voulais simplement ne pas utiliser addclient, deleteclient mais les operateur + et -!

  4. #4
    Membre expérimenté Avatar de Kazh Du
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 152
    Par défaut
    1er pb :
    ta fonction ne fait pas ce que tu veux ?
    que veux tu quelle fasse précisément ? (afficher le contenu de ta variable ?)
    que fait elle actuellement ? (afficher la taille de de ta variable ? ou rien du tout = beau plantage)

    2eme pb :
    Si tu veux vraiment les utiliser (libre à toi) il est préférable de définir l'opérateur += (et -=) plutôt que + et - car ces derniers ne devraientpas modifier les objets, et SURTOUT c'est eux que tu as utilisé dans ta fonction. + et += ne sont pas équivalents. Et surtout veille à bien faire la distinction entre pointeur et référence, ce que tu n'avais pas fais (d'où ton erreur).

    PS : Je comprend qu'il est tentant de vouloir les utiliser, mais dans ton cas ça ne se justifie pas, il faut penser en terme de lisibilité et de compréhension du code. Pense à des listes : tu peux ajouter un objet à ta liste avec add(objet) et tu pourrais vouloir créer la fusion de 2 listes avec un +.

    PS 2 : dans le cas d'un pointeur, l'additionner avec un entier (ce que ton compilateur s'attendait à faire visiblement : un pointeur peut parfois être traité comme un entier) reviens à le faire avancer d'autant d'octets, c'est ce qu'il se passe avec un tableau (avec un sizeof en plus ).

  5. #5
    Membre très actif
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Par défaut
    Premier probleme:
    En gros, j'ai dans ma classe ceci:
    Quand je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *p = "01 02 05 6b 6b 6b 6b 6b ff aa";
    Packet *pk = new Packet(*p);
    Mon constructeur va remplir bytes avec (dans ce cas)
    1,2,5,107,107,107,107,107,255,170

    je veux, pouvoir faire
    int a = pk->read();
    int a = pk->read<int>();
    int a = pk->read(<int>);
    int a;
    pk->read(&a);

    et, que je puisse egalement faire
    long L = pk->read();
    char c[a] = pk->read();

    Et au final, la fonction read, prendra la taille de ce que j'aimerais lire (int/char = 1byte, long = 2 bytes, "string" = taille du char[])

    Pour le deuxieme probleme,
    J'ai simplement vu que l'on pouvait simplifier un "add()" ou delete() avec les operateurs en les surchargeant.
    Donc ma question est plutot, niveau rapidité, operateur surchargés ou fonctions ?

    merci,
    nico

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Déjà, je me demande pourquoi utiliser un pointeur sur queue<byte> (je présume que c'est en fait une std::queue !)

    Tu te compliques la vie inutilement en
    • devant gérer par toi meme la mémoire allouée à ce pointeur
    • rendant la copie de ton objet beaucoup moins sécurisante (tu n'as pas défini le constructeur par copie et l'opérateur d'affectation, ce qui fait que tu vas etre confronté à de sérieux problèmes de double tentatives de libération de la mémoire)
    • devant manipuler le membre (la queue) au travers s'une syntaxe différente
    • violant le principe de la responsabilité unique, parce que tu rajoute à ta classe, dont la responsabilité devrait n'être que de gérer des bytes, le fait de devoir gérer également... l'élément qui permet de les maintenir en mémoire
    • ... j'oublie peut etre une ou l'autre chose

    J'en profite d'ailleurs pour faire la meme remarque pour l'utilisation de ta classe : pourquoi utiliser un pointeur, avec tous les problèmes que cela sous entend, alors qu'il serait "si facile" d'utiliser un objet tout à fait classique

    Ensuite, je suis d'accord avec Kazh Du : les opérateur + et += servent par convention pour des additions (au sens mathématique), voir pour des concaténations (cf std::string) ...

    Or, ce que tu fais ici, c'est rajouter "quelque chose" à un paquet...

    Tu détourne donc l'opérateur de l'utilisation que "l'imaginaire collectif" envisage pour lui, et ce n'est vraiment pas, mais alors vraiment pas une bonne idée.

    Si tu devais définir un opérateur + (ou +=) tu devrais le définir de sorte à... additionner deux objets de type "Packet", pour autant que cela ait un sens!

    Enfin, les templates sont un monde magnifique, mais ils doivent venir "en supplément" du paradigme OO...

    Il est utile de les utiliser s'il y a vraiment un intérêt particulier à le faire (pour éviter la copie de code, par exemple), mais, vouloir utiliser les template "pour le plaisir de les utiliser" n'a finalement pas beaucoup de sens si leur utilisation ne fait que "te compliquer la vie" !

    L'idée des tempalte, c'est de se dire que "si je ne sais pas exactement quel type de donnée j'aurai à manipuler, je sais néanmoins parfaitement comment je dois les manipuler".

    La question à se poser est donc "est il possible d'imaginer une logique quelconque qui me permettra de manipuler aussi bien des int, des long, des double, des byte ou des float (en somme : n'importe quel type de donnée compatible ) de sorte à pouvoir les insérer de manière cohérente dans la queue de byte " et, surtout "est-ce que cela me facilitera réellement la tache "

    J'ai envie de dire que, maintenant que les opérateurs sont définis pour l'ensemble des types susceptibles d'être utilisés, peut etre te fais tu simplement du mal pour rien
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Réponses: 22
    Dernier message: 17/07/2008, 09h51
  2. souci classe template et surcharge operateur
    Par loicounet dans le forum Langage
    Réponses: 8
    Dernier message: 28/04/2008, 15h01
  3. Optimisation Listechainé avec template et operateur surchargé.
    Par Alain Defrance dans le forum Langage
    Réponses: 8
    Dernier message: 29/12/2007, 18h25
  4. Réponses: 6
    Dernier message: 12/07/2007, 18h18
  5. [Template] Surcharge operateur
    Par juls64 dans le forum C++
    Réponses: 7
    Dernier message: 04/05/2007, 19h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo