Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [SFML2] Problème no match operator << >>... avec sf::Packet  (Lu 8291 fois)

0 Membres et 1 Invité sur ce sujet

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Bonjour à tous et à toutes :)

J'ai lu dans la doc (directement du fichier Packet.hpp de la version 2) qu'il est possible de surcharger l'opérateur << et >> afin d'intégrer nos propres structure de données.

Voilà le petit problème : la doc montre comment surcharger avec des fonctions devrais-je dire puisque c'est à l'extérieur d'une classe quelconque. Seulement, j'aimerais bien qu'il s'agisse de méthode à une classe (EncryptedPacket) qui hérite publiquement de sf::Packet.

Seulement voilà, selon ce que je constate, il est impossible d'appeler une surcharge X (de <<, >>) à l'intérieur d'une surcharge Y des opérateur << et >>.

Exemple :
EncryptedPacket& EncryptedPacket::operator <<(const DataConnection& data)
{//Toutes ces données sont des sf::Int32 ou std::string (qui sont déjà surchargé dans sf::Packet)
    *(this) << data.dataType << data.clientVersion << data.user << data.password << data.server;
    return *this;
}
 

J'ai le droit à : no match for 'operator<<' in '*(net::EncryptedPacket*)this << data.dataType.

J'ai alors pensé aller voir dans le code source afin de créer une copie des surcharges utilisées (string et Int32) :
Int32 ToWrite = htonl(data.dataType);
append(&ToWrite, sizeof(ToWrite));//...
 

Mais voilà quand on arrive avec l'opérateur >>, impossible d'accéder à l'élément m_readPos :
if (checkSize(sizeof(data.dataType)))
{
    data.dataType = ntohl(*reinterpret_cast<const Int32*>(&m_data[m_readPos]));
    m_readPos += sizeof(data.dataType);
}
 

Parce que cet attribut est privé dans sf::Packet. Ce qui veut forcément dire que je ne suis pas sensé faire une tel manipulation...

Existe-t-il une solution afin d'utiliser une surcharge des opérateurs << et >> dans une autre surcharge de ces deux opérateurs ?

Merci beaucoup et bonne journée ! ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #1 le: Mai 08, 2012, 08:46:42 am »
Pourquoi te bats-tu contre l'API ? La façon de faire c'est de surcharger ces opérateurs entre sf::Packet et ta structure de donnée perso, avec des fonctions non-membres.

Il n'y a strictement aucune bonne raison de vouloir faire autrement, vraiment.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #2 le: Mai 08, 2012, 02:03:33 pm »
Bon... ok...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #3 le: Mai 08, 2012, 03:32:13 pm »
Mais s'il y a quelque chose qui te chiffonne on peut en parler hein ;)
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #4 le: Mai 08, 2012, 10:34:53 pm »
J'aimerais savoir pourquoi on ne peut pas appeler une surcharge dans une surcharge comme je tentais de le faire.

Ensuite, je pensais que ces méthodes devait appartenir à la classe elle-même puisqu'il n'est d'aucun sens d'appeler une surcharge de cette classe si on ne possède pas déjà une instance de cette classe... Mais bien évidemment, on ne pourra pas l'appeler même si on n'a pas une instance puisqu'il faut une instance (vu que c'est en paramètre).

Je vais donc me contenter de les mettre dans le fichier de la classe à la suite de la classe elle-même.

Ce que je trouve bizarre en fait, c'est que dans la classe Packet, les surcharges sont dans la classe, sauf que si je crée une extension, là faut les mettre à l'extérieur de la classe.

Je comprends l'utilité du fonctionnement actuel. Par exemple, si on veut ajouter une surcharge à Packet sans rien modifier d'autre, ça serait stupide de créer une classe héritant de Packet simplement pour ajouter des surcharges d'opérateur.

Par contre, quand on crée une classe qui a d'autres objectifs très précis (comme l'encryptage de données ici), je pensais qu'il serait logique ou pratique de les intégrer dans la classe voilà tout :)

Mais bien sûr, au final, ça ne change pas grand chose de les ajouter dans la classe ou après la classe ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #5 le: Mai 09, 2012, 08:25:05 am »
Citer
J'aimerais savoir pourquoi on ne peut pas appeler une surcharge dans une surcharge comme je tentais de le faire.
Je ne sais pas, quel est le type de data.dataType?

Citer
Ensuite, je pensais que ces méthodes devait appartenir à la classe elle-même puisqu'il n'est d'aucun sens d'appeler une surcharge de cette classe si on ne possède pas déjà une instance de cette classe... Mais bien évidemment, on ne pourra pas l'appeler même si on n'a pas une instance puisqu'il faut une instance (vu que c'est en paramètre).
Oui. En fait tant que la fonction n'utilise que des données/fonctions publiques de la classe, alors il n'y a aucun intérêt à en faire une fonction membre. C'est un ajout externe à la classe.

Citer
Ce que je trouve bizarre en fait, c'est que dans la classe Packet, les surcharges sont dans la classe, sauf que si je crée une extension, là faut les mettre à l'extérieur de la classe.
Ce qui est dans sf::Packet ce sont les surcharges pour les types primitifs, qui nécessitent d'accéder aux membres privés de la classe. Mais ensuite, une fois ces fonctions disponibles, tout le reste peut simplement être construit par dessus, sans avoir à faire une intrusion dans la classe de paquets.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #6 le: Mai 09, 2012, 01:34:34 pm »
Ah d'accord je comprends mieux maintenant :)

Mais justement, en fait toutes mes données sont des données primitifs (dataType c'est un sf::Int32 et les autres sont des std::string qui sont donc intégrer à sf::Packet).

Et quand j'appelle donc deux surcharge une dans l'autre euh... ça me fous une belle erreur comme quoi que la surcharge pour *this << dataType n'existe pas nul part alors que dataType est bel et bien un Int32 :o

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #7 le: Mai 09, 2012, 02:05:41 pm »
Bah, ça devrait marcher.

J'ai vraiment très peu de temps libre en ce moment pour tester ce genre de choses. Ce qui serait vraimen top ce serait que tu écrives un code complet minimal qui reproduit cette situation (une dérivée de sf::Packet, une structure perso qui contient un sf::Int32, et une surcharge de <<) que je puisse tester ça.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #8 le: Mai 09, 2012, 10:36:35 pm »
Voici donc le plus basique que je peux faire en un fichier :)

#include <SFML/Network.hpp>

using namespace std;
using namespace sf;

struct Data
{
    Int32 dataType;
};

class EncryptedPacket : public Packet
{
public:
    EncryptedPacket& operator <<(const Data& data)
    {
        *this << data.dataType;
        return *this;
    }
};

int main()
{
    Data data;
    EncryptedPacket packet;
    packet << data;
    return 0;
}
 

Erreurs :
Citer
16 : no match for 'operator<<' in '*(EncryptedPacket*)this << data->Data::dataType'
Citer
14 : candidates are EncryptedPacket& EncryptedPacket::operator<<(const Data&)
Citer
IpAddress.hpp 282 : std::ostream& sf::operator<<(std::ostream&, const sf::IpAddress&)

Je comprends même pas pourquoi une erreur vient du fichier IpAddress... je ne fais pas du tout appel à ce fichier pourtant. Erreur interne ou je fais une boulette dans mon code ? ???

C'est le même problème pour l'opérateur inverse :(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #9 le: Mai 10, 2012, 08:26:59 am »
Ah ben nickel, merci beaucoup :)

Bon ça me laisse assez perplexe. Ces deux modifications fonctionnent :

EncryptedPacket& operator <<(EncryptedPacket& packet, const Data& data)
{
    packet << data.dataType;
    return packet;
}
 

class EncryptedPacket : public Packet
{
public:
    EncryptedPacket& operator <<(const Data& data)
    {
        Packet& p = *this;
        p << data.dataType;
        return *this;
    }
};
 

Faudrait creuser, sûrement une règle de C++ de derrière les fagots qui s'applique dans ce cas particulier. Ou alors on loupe un truc tout bête ;D

Citer
Je comprends même pas pourquoi une erreur vient du fichier IpAddress...
Ce n'est pas le cas, il te liste simplement toutes les surcharges de << qu'il a trouvées vu qu'il n'en trouve aucune qui correspond.
Laurent Gomila - SFML developer

minirop

  • Sr. Member
  • ****
  • Messages: 254
    • Voir le profil
    • http://dev.peyj.com
Re : Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #10 le: Mai 10, 2012, 10:36:17 am »
Faudrait creuser, sûrement une règle de C++ de derrière les fagots qui s'applique dans ce cas particulier. Ou alors on loupe un truc tout bête ;D
parce qu'une surcharge dans une classe fille "supprime" les versions de la classe mère ?
class A
{
public:
        void pouet()
        {
                std::cout << "A::pouet" << std::endl;
        };
};

class B : public A
{
public:
        void pouet(int x)
        {
                std::cout << "B::pouet " << x << std::endl;
        };
};

int main(int argc, char** argv)
{
        B b;
        b.pouet();
       
        return 0;
}
renvoie
Citer
main.cpp: In function 'int main(int, char**)':
main.cpp:24:10: error: no matching function for call to 'B::pouet()'
main.cpp:15:7: note: candidate is: void B::pouet(int)
« Modifié: Mai 10, 2012, 10:44:09 am par Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #11 le: Mai 10, 2012, 10:45:34 am »
Ah oui, j'avais oublié le masquage.

Du coup, un petit
using sf::Packet::operator<<;
Dans la classe mère devrait faire l'affaire.

Mais bon, faut pas perdre de vue que la bonne façon de faire, c'est de toute façon avec des opérateurs non-membres.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #12 le: Mai 10, 2012, 12:52:14 pm »
Mais si je veux créer cette classe afin que d'autres classes en héritent, c'est là que ça devient tout à fait logique de les intégrer dedans non ? :)

Et euh... j'ai loupé un truc ? Le masquage s'applique même si les deux méthodes n'ont pas la même signature ? ???
« Modifié: Mai 10, 2012, 12:56:26 pm par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #13 le: Mai 10, 2012, 01:17:45 pm »
Citer
Mais si je veux créer cette classe afin que d'autres classes en héritent, c'est là que ça devient tout à fait logique de les intégrer dedans non ?
Le fait d'avoir les opérateurs << en membre ou non ne fait aucune différence à ce niveau. Tu pourras toujours passer un DerivedEncryptedPacket à ta surcharge qui prend en paramètre un EncryptedPacket& ou Packet&.

Citer
Et euh... j'ai loupé un truc ? Le masquage s'applique même si les deux méthodes n'ont pas la même signature ?
Oui.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Problème no match operator << >>... avec sf::Packet
« Réponse #14 le: Mai 10, 2012, 10:23:50 pm »
Ah ouais c'est vrai si les operateurs suivent la classe ils seront automatiquement inclus et donc accessible :)

Merci pour tout Laurent tu m'aides vraiment gros sérieux !  :)

ps. Il faut que je te le dise aussi : SFML est vraiment géniale : tu fais vraiment du bon bouleau ! N'arrête surtout pas !!!  ;) Parce que moi je suis tombé en amour avec ma blonde la SFML. Elle est tellement bien faite et si bien pensée ;D