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

C++ Discussion :

Problème de redéfinition d'une fonction virtuelle avec un type d'argument différent


Sujet :

C++

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2004
    Messages : 4
    Points : 5
    Points
    5
    Par défaut Problème de redéfinition d'une fonction virtuelle avec un type d'argument différent
    Bonjour,
    Je voudrais savoir si d'une manière ou d'une autre, il est possible d'avoir une fonction membre virtual d'une classe mère qui serait redéfinie dans les classes filles mais avec un type d'argument différent!
    Je m'explique : mon programme est une application qui communique via des sockets avec plusieurs autres applications. J'ai donc créé une classe A (classe mère) qui représente globalement un correspondant pour mon appli, et des classe filles B, C, et D qui représentent chacune spécifiquement un de mes correspondants. Chaque fois que je reçois un "message" de l'un de ces correspondants, je dois faire un traitement spécifique derrière, donc j'ai une méthode de la classe mère "traiterMessage(TypeMessage &message)" implémentée dans chaque classe fille. Le problème, c'est que tous ces correspondants ne communiquent pas avec mon appli avec le même protocole, donc le type même de message reçu est différent (et la classe qui représente mon objet message).
    Or, mon appli ayant une interface serveur, elle ne sait pas au moment où elle reçoit le message de qui il provient.
    Un bout de code pour l'exemple :

    Dans mon .h :

    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
    class Protocole1
    {}
     
    class A
    {
        virtual void traiterMessage(Protocole1 &message)=0;
    }
     
    class B : public A
    {
        void traiterMessage(Protocole1 &message);
    }
     
    class C : public A
    {
        void traiterMessage(Protocole1 &message);
    }
     
     
    class D : public A
    {
       void traiterMessage(Protocole2 &message);
    }
    Et dans mon .cpp, j'ai 2 serveurs, pour les 2 protocoles différents, donc le premier j'ai :

    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
    Serveur1::donneesrecues()
    {
       A* monCorrespondant;
       Protocole1 message;
     
       ......
       moncorrespondant->traiterMessage(message); 
    }
     
     
    Serveur2::donneesrecues()
    {
       A* monCorrespondant;
       Protocole2 message;
     
       ...
     
      monCorrespondant->traiterMessage(message);
    }
    Voila, je ne sais pas si c'est tres clair, enfin toujours est it que ca ne compile pas puisque la méthode traiterMessage(Protocole1) n'est pas implémentée pour une des classe filles (la classe D).
    Je me demandais donc si il y avait de faire cela "proprement", sans etre obligée de définir directement dans la classe mère 2 méthodes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    traiterMessage(Protocole1)
    traiterMessage(Protocole2)
    Merci!

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Déclare une classe abstraite BaseProtocole que tu utilises comme paramètre dans A.
    Puis dérive Protocole1/2/3 de BaseProtocole et utilise-les respectivement dans B/C/D::donneesrecues().

    Il y aura probablement un ProtocoleN* ptr = dynamic_cast<ProtocoleN>(ptrInstanceBaseProto); à caser quelque part.

  3. #3
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Citation Envoyé par cob59 Voir le message
    Il y aura probablement un ProtocoleN* ptr = dynamic_cast<ProtocoleN>(ptrInstanceBaseProto); à caser quelque part.
    Si tu peut evite le dynamic_cast c'est moche. Si ta classe de base est bien concue tu peut utiliser le polymorphisme.

  4. #4
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    dynamic_cast n'est pas moche en soi, ça dépend comment on s'en sert.
    Prendre un pointeur et faire un dynamic_cast sur toutes les classes filles possibles pour implémenter différents comportements, ça c'est moche.

    Mais dans ce cas précis, on sait avec quel type de protocole on veut travailler, et on se trimbale un pointeur sur la classe mère pour un soucis d'interfaçage. Si le dynamic_cast échoue, alors l'utilisateur a fourni un mauvais protocole et on peut quitter la fonction, sinon on a directement un pointeur sur le bon protocole.

  5. #5
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonsoir,

    Personnelement je ferais ca sous forme d'un visiteur, quelque chose comme :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    //Class de bases pour implémenter un visiteur acyclique
    struct Protocol
    { virtual ~Protocol(){} };
     
    struct A
    {
      virtual void recieved(Protocol&) =0; 
    };
     
     
    //Un premier type de correspondant et une classe de procole associée
    struct B : A
    { void recieved(Protocol&); };
     
    struct ProtocolB : Protocol
    { virtual void process(B&) =0; };
     
    void B::recieved(Protocol& m)
    {
      if ( ProtocolB* p = dynamic_cast<ProtocolB*>(&m) )
        p->process(*this);
      //Si le protocole ne peut être traiter
      //Ne rien faire
    }
     
     
    //Un second
    struct C : A
    { void recieved(Protocol&); };
     
    struct ProtocolC : Protocol
    { virtual void process(C&) =0; };
     
    void C::recieved(Protocol& m)
    {
      if ( ProtocolC* p = dynamic_cast<ProtocolC*>(&m) )
        p->process(*this);
      //Idem
    }
     
     
    //Un premier procole dédié aux correspondant de type B
    struct Protocol1 : ProtocolB
    {
      void process(B&)
      { /*implémentation*/ }
    };
     
    //Un deuxième pour les correspondant de type C
    struct Protocol2 : ProtocolC
    {
      void process(C&)
      { /*implémentation*/ }
    };
     
    //Un protocole qui fonctionne pour les deux
    struct Protocol3 : ProtocolB, ProtocolC
    {
      void process(B&)
      { /*implémentation*/ }
      void process(C&)
      { /*implémentation*/ }
    };
    (compile mais est lacunaire)

  6. #6
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Citation Envoyé par Kalith Voir le message
    dynamic_cast n'est pas moche en soi, ça dépend comment on s'en sert.
    Prendre un pointeur et faire un dynamic_cast sur toutes les classes filles possibles pour implémenter différents comportements, ça c'est moche.

    Mais dans ce cas précis, on sait avec quel type de protocole on veut travailler, et on se trimbale un pointeur sur la classe mère pour un soucis d'interfaçage. Si le dynamic_cast échoue, alors l'utilisateur a fourni un mauvais protocole et on peut quitter la fonction, sinon on a directement un pointeur sur le bon protocole.
    Le fait de devoir faire cast dans le bon type indique que tu a fait une "mauvaise conception". Tu ne devrait pas avoir besoin de connaitre le type de l'objet. Seul l'objet connait son type et sait ce qu'il doit faire.

    Si tu fait du debug c'est toujours intéréssant mais dans le cas contraire il faut te poser une question sur ton interface de base dans laquelle il doit manqué quelque chose.

  7. #7
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Citation Envoyé par Kalite Voir le message
    Seul l'objet connait son type et sait ce qu'il doit faire.
    Oui, sauf que là tu te trouves dans une situation où il y a interaction (si l'on peut dire) entre deux objets, le protocole et le serveur. Si le comportement de l'un et de l'autre se borne (ou peut se résumer de manière logique) à redéfinir des fonctions virtuelles des classes de bases, alors tu n'as aucun problème. Sinon il faut obligatoirement, à un moment où un autre, que tu saches explicitement quels sont les types réellement mis en jeu.

    La première option c'est de déterminer le type du protocole dans la classe de serveur, la seconde à l'opposé et comme l'a décrit Flob90, c'est de déterminer le type de serveur dans une fonction du protocole.

    Si le dynamic_cast te pose vraiment un problème, imagine alors plutôt quelque chose du style :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    struct Protocol
    {
        enum Type
        {
            HTTP,
            HTTPS,
            FTP,
            ...
        } type;
     
     
        void* data; // ça c'est moche, il a moyen de faire plus propre 
        uint  size; // (type erasure, etc), mais c'est pour l'exemple
    };
     
    class Serveur
    {
    public :
     
        Serveur();
        virtual ~Serveur();
     
        virtual void traiterMessage(const Protocol& p) = 0;
        ...
    };
     
    class ServeurA : public Serveur
    {
    public :
     
        void traiterMessage(const Protocol& p)
        {
            if (p.type == Protocol::HTTP || p.type == Protocol::HTTPS)
            {
                ...
            }
        }
    };
     
    class ServeurB : public Serveur
    {
    public :
     
        void traiterMessage(const Protocol& p)
        {
            if (p.type == Protocol::FTP)
            {
                ...
            }
        }
    };
    Le principe est le même, mais on n'utilise pas de dynamic_cast

  8. #8
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Le dynamic_cast ne me pose pas de problème cela mais arrivé de l'utiliser.
    Je voulais juste dire qu'il faut éviter de s'en servir à tous bout de champs.

    Genre: je veut pas me prendre la tête sur la conception je met une rustine et puis voilà.
    Après lecture "approfondie" de ton poste, ce n'est pas ce que tu avait proposé.

    Comme tu le dit, le plus gros problème d'astrid c'est de savoir où tu est capable de déterminer le type de protocole.
    Le connait-on lors de la connexion du client?
    --> Liste client / protocole a conserver par le serveur par exemple.
    Faut-il le déterminer à la volé en fonction des trames qui arrive?

    PS :
    Citation Envoyé par Kalith Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct Protocol
    {
        enum Type
        {
            HTTP,
            HTTPS,
            FTP,
            ...
        } type;
     
     
        void* data; // ça c'est moche, il a moyen de faire plus propre
        uint  size; // (type erasure, etc), mais c'est pour l'exemple
    };
    C'est vraiment très moche quand on fait de l'objet, ca c'est sur.

  9. #9
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Citation Envoyé par Kalite Voir le message
    Le dynamic_cast ne me pose pas de problème cela m'est arrivé de l'utiliser.
    Je voulais juste dire qu'il faut éviter de c'en servir à tous bout de champs.
    Là je suis d'accord avec toi. Mais de là à dire que c'est moche, il y a un pas que je ne franchirai pas

  10. #10
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    En général, chaque fois que tu as besoin d’un dynamic_cast, tu gagnerais à utiliser un variant. Ça t’offre des contrôles à la compilation au lieu qu’ils soient à l’exécution.

    Ensuite, vouloir redéfinir des méthodes en changeant le type d’argument, c’est en violation directe du LSP. Donc c’est très souvent très mal . Ici, la classe de base sert de dispatcher. Utiliser l’héritage pour faire le dispatch n’est pas possible, il te faut donc implémenter toi-même ton dispatch. Plutôt que de le bricoler avec l’héritage et du dynamic_cast, autant faire un vrai dispatcher et se passer d’héritage (sauf si j’ai loupé un truc, il ne me semble pas apporter grand chose dans le cas présent).

  11. #11
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonjour,

    @Kalite:
    Le fait de devoir faire cast dans le bon type indique que tu a fait une "mauvaise conception".
    Non, qu'il y a peut-être un problème de conception, pas qu'il y en a un. Là ca ne pose pas de problème, on est plus ou moins dans un cas de dispatch (double, le traitement dépend du type réel de 2 objets), le dynamic_cast est une solution viable (on peut aussi passer par un visiteur cyclique, mais personnelement je préfère un visiteur acyclique avec un dynamic_cast bien placé qu'une architecture avec une dépendance circulaire).

    Comme tu le dit, le plus gros problème d'astrid c'est de savoir où tu est capable de déterminer le type de protocole.
    Le connait-on lors de la connexion du client?
    L'OP a donné un code d'exemple qui répond à ta question. Lors de l'appel de la méthode il connait le type du protocole mais pas le type réel du "correspondant".

    @white_tentacle:

    Pas exactement, un changement du type de l'argument du type contra-variant n'est pas un viol du LSP, par contre il est quand même interdit en C++.

    Et je ne vois pas en quoi faire un dispatcher c'est se passer nécessairement d'un dynamic_cast, si tu prends les dispatcher de Loki certains sont basés sur un dynamic_cast, le choix du dispatcher dépend de la situations (et vu la situation et le tableau d'Alexandrescu (p 297) c'est bien un dispatcher basé sur un dynamic_cast le mieux adapté). Cependant, je trouve que l'utilisation d'un dispatcher "tout fait" serait ici un peu lourde, je préfère clairement un visiteur (en un sens c'est un dispatcher, mais utilisé le terme visiteur évite que l'OP se retrouve sur des articles traitant de multi-dispatch, AMA), bien plus léger à mettre en oeuvre. (et peut-être plus efficase ici : à bencher)

  12. #12
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    Pas exactement, un changement du type de l'argument du type contra-variant n'est pas un viol du LSP, par contre il est quand même interdit en C++.
    C’est tout à fait exact, de même que d’autres changement de type pourraient être envisagés car résultant d’un élargissement des préconditions. Je ne voulais juste pas rentrer à ce niveau de détail, vu que ce que veut faire l’op était clairement une restriction des préconditions .

    Et je ne vois pas en quoi faire un dispatcher c'est se passer nécessairement d'un dynamic_cast, si tu prends les dispatcher de Loki certains sont basés sur un dynamic_cast, le choix du dispatcher dépend de la situations (et vu la situation et le tableau d'Alexandrescu (p 297) c'est bien un dispatcher basé sur un dynamic_cast le mieux adapté). Cependant, je trouve que l'utilisation d'un dispatcher "tout fait" serait ici un peu lourde, je préfère clairement un visiteur (en un sens c'est un dispatcher, mais utilisé le terme visiteur évite que l'OP se retrouve sur des articles traitant de multi-dispatch, AMA), bien plus léger à mettre en oeuvre. (et peut-être plus efficase ici : à bencher)
    Je me suis mal exprimé alors. Je pense que quitte à faire un dispatcher, il doit avoir une connaissance statique de l’ensemble des classes vers lesquelles il dispatche (histoire que le jour où tu en rajoutes une, ça ne compile plus partout où tu oublies de la gérer).

    À ma connaissance, le variant est un meilleur moyen d’avoir ce résultat que l’héritage. J’ai une trop mauvaise expérience de dispatcher en C# ou java fait en utilisant l’introspection, et où rajouter un type se révèle un cauchemar. Et je ne vois pas de plus-value à l’héritage polymorphique ici. Sinon, comme tu le dis, un visiteur (le variant de boost fonctionne avec des visiteurs).

  13. #13
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    L'OP a donné un code d'exemple qui répond à ta question. Lors de l'appel de la méthode il connait le type du protocole mais pas le type réel du "correspondant".
    Mes plus sincère excuse, j'ai mal lu la problématique.

    Citation Envoyé par Flob90 Voir le message
    Non, qu'il y a peut-être un problème de conception, pas qu'il y en a un. Là ca ne pose pas de problème, on est plus ou moins dans un cas de dispatch (double, le traitement dépend du type réel de 2 objets), le dynamic_cast est une solution viable (on peut aussi passer par un visiteur cyclique, mais personnelement je préfère un visiteur acyclique avec un dynamic_cast bien placé qu'une architecture avec une dépendance circulaire).
    Euh la j'avoue tu m'a perdue (J'ai l'impression d'être un ignorant alors que normalement j'arrive a me débrouiller sans soucis).Le début sa va mais je comprend pas cette histoire de visiteur cyclique - acyclique.

  14. #14
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @Kalite: Plutôt que de me lancer dans une explication je préfère te rediriger vers cette article d'Emmanuel Deloget (il explique probablement mieux que je ne le ferais ) : http://blog.emmanueldeloget.com/inde...comme-visiteur , en espérant que ca éclairecisse mon message.

    @white_tentacle: J'avais en effet mal compris ton premier message alors, je pense qu'on est d'accord sur les différentes solutions possibles au problème de l'OP

  15. #15
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    @Kalite: Plutôt que de me lancer dans une explication je préfère te rediriger vers cette article d'Emmanuel Deloget (il explique probablement mieux que je ne le ferais ) : http://blog.emmanueldeloget.com/inde...comme-visiteur , en espérant que ca éclairecisse mon message.
    Merci pour le cour. Effectivement c'est plus clair. Je comprend la solution mais la dernière fois que j'ai implémenté un visiteur je me souvient pas avoir eu le problème. Je note quand même.

    @Flob90:
    J'en profite pour savoir si tu peut pas m'éguiller sur mon problème.
    Voir post http://www.developpez.net/forums/d11...ion-protocole/

Discussions similaires

  1. Probléme d'appel d'une fonction avec EF
    Par kaka83185 dans le forum Accès aux données
    Réponses: 6
    Dernier message: 03/05/2012, 10h27
  2. Limiter la redéfinition d'une fonction virtuelle ?
    Par N0vember dans le forum Débuter
    Réponses: 5
    Dernier message: 30/11/2009, 09h58
  3. Réponses: 2
    Dernier message: 02/10/2008, 16h37
  4. Réponses: 7
    Dernier message: 05/05/2006, 09h48
  5. Creation d'une fonction temporaire avec droit datareader
    Par Bjuice2 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 26/10/2004, 14h26

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