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

Visual C++ Discussion :

impl�mentation d'interfaces multiples : limitation de C++ ou du compilo VS2005 ?


Sujet :

Visual C++

  1. #1
    Membre �clair�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par d�faut impl�mentation d'interfaces multiples : limitation de C++ ou du compilo VS2005 ?
    Bon, je m'explique ;
    suite � une impl�mentation de Garbage Collector enfin bref passons ; je viens de m'apercevoir que l'ordre de d�claration de l'impl�mentation d'interfaces dans une classe � une importance (chose que je n'ai jamais vue en C# et en Java).

    Je m'explique, voil� mon exemple de code :
    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
     
    interface I1
    {
    public :
    	virtual void SetI1 () = 0;
    };
     
    interface IInutil
    {
    public :
    	virtual void SetIInutil () = 0;
    };
     
    class JeCollectionneCeQuiDerivedeI1
    {
    public :
    	void AddElement (I1* param)
    	{
    		CString coincoin("coin coin");
    	}
    };
     
    class MaClasseQuiHeriteDesDeuxInterface : public I1, public IInutil
    {
    public :
    	MaClasseQuiHeriteDesDeuxInterface (JeCollectionneCeQuiDerivedeI1& jccqdi)
    	{
    		jccqdi.AddElement(this);
    	};
    	void SetI1 () {};
    	void SetIInutil () {};
    };
    En voici l'utilisation :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    			JeCollectionneCeQuiDerivedeI1 jccqddi;
    			MaClasseQuiHeriteDesDeuxInterface* mcqhddi = new MaClasseQuiHeriteDesDeuxInterface(jccqddi);
    Tout se passe impec quand je passe dans le constructeur de la variable mcqhddi, le this pass� en param�tre de void AddElement (I1* param) a la m�me adresse que this c'est-�-dire adresse de this = adresse de param.

    Par contre, si j'inverse l'ordre d'impl�mentation des interfaces dans ma classe :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    ...
    class MaClasseQuiHeriteDesDeuxInterface : public IInutil, public I1
    ...
    alors l� dans le constructeur, je me retrouve avec un pointeur this qui est de 4 bits inf�rieur � la valeur de param. "Ol�, c'est super !!!". Donc il doit y avoir un probl�me de vtbl, mon tableau de pointeur de fonctions virtuelles sur ma classe d�pend de l'ordre de d�claration d'impl�mentation de mes interfaces dans cette classe. Ce qui me para�t plus que bizarre
    Je viens de me repencher sur le bouquin "Mieux d�velopper avec C++" et sur le bouquin de Stroujstrup (excusez pour l'orthographe), rien pas d'indice.
    Donc si vous pouviez m'�clairer et me dire si vous aviez d�j� eu ce cas-l�.
    Ou bien alors quelque-chose m'�chappe et merci de bien vouloir m'�clairer ou alors ... tant pis

  2. #2
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Normal que tu n'aies pas vu �a en Java ou C#, ils ne supportent pas l'h�ritage multiple. Si tu as une classe C qui h�rite de A et de B, Il faut bien stocker les donn�es membre de A et de B quelque part, par exemple en commen�ant par celles de A, puis celles de B (je ne sais plus si l'ordre est sp�cifi�, mais �a n'y change rien).

    Donc, dans une fonction qui prend un A*, pas de probl�me, on peut lui passer directement l'adresse de ton C. Pour qu'une fonction qui prend un B* retrouve bien les donn�es qui viennent de B, il faut appliquer un offset � ton C*. C'est cet offset qui doit provoquer le d�calage que tu vois. Donc tout va bien.

    Et la gestion de ces offsets est probablement une des raisons pour lesquelles certains impl�menteurs de langages ont peur de l'h�ritage multiple.
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  3. #3
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    C'est le cas aussi en java, o� l'impl�mentation d'interfaces multiples �vite les probl�mes de donn�es du � l'h�ritage multiple (notamment dans le cas d'h�ritage en losange).

    Avec les interfaces, la seule donn�e dupliqu�e et le pointeur de vtable, qui est constant et inaccessible � l'utilisateur.

    Mais �a ne change rien au fait qu'une classe qui impl�mente deux interfaces poss�de deux pointeurs de vtable. Ils sont donc situ�s � deux endroits diff�rents de la classe.
    Pour r�gler le probl�me, la vtable de la seconde interface ne pointe pas directement sur les fonctions membres, mais sur des "thunk" qui font une soustraction sur le pointeur this avant d'appeler la fonction elle-m�me.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre �clair�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par d�faut
    Citation Envoy� par JolyLoic
    Normal que tu n'aies pas vu �a en Java ou C#, ils ne supportent pas l'h�ritage multiple.
    Euh ... mon exemple montre bien un h�ritage d'INTRERFACE multiple et non un h�ritage de CLASSE multiple.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Pour régler le problème, la vtable de la seconde interface ne pointe pas directement sur les fonctions membres, mais sur des "thunk" qui font une soustraction sur le pointeur this avant d'appeler la fonction elle-même.
    Tu veux dire par l� que si j'ai par exemple une classe CC qui impl�mente d'abord I1, I2 puis I3 ; si une m�thode d'une classe X prend en param�tre un pointeur de I3 et que je passe mon pointeur this de CC � la m�thode de la classe X, le this se transformera en this.CC+(offset m�thodes virtuelles de I1)+(offset m�thodes virtuelles de I2) et donc pointeur au d�but de la vtbl de l'interface I3 ?

  5. #5
    Membre �clair�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par d�faut
    Citation Envoy� par ep31
    Euh ... mon exemple montre bien un h�ritage d'INTRERFACE multiple et non un h�ritage de CLASSE multiple.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Pour régler le problème, la vtable de la seconde interface ne pointe pas directement sur les fonctions membres, mais sur des "thunk" qui font une soustraction sur le pointeur this avant d'appeler la fonction elle-même.
    Tu veux dire par l� que si j'ai par exemple une classe CC qui impl�mente d'abord I1, I2 puis I3 ; si une m�thode d'une classe X prend en param�tre un pointeur de I3 et que je passe mon pointeur this de CC � la m�thode de la classe X, le this se transformera en this.CC+(offset m�thodes virtuelles de I1)+(offset m�thodes virtuelles de I2) et donc pointera au d�but de la vtbl de l'interface I3 ?

  6. #6
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Pour �tre pr�cis, ce ne sera pas exactement this qui sera pass�, mais this + offset(pointeur vtable I3).
    Typiquement, cet offset est �gal � sizeof(classe m�re) + sizeof(pointeur vtable I1) + sizeof(pointeur vtable I2).
    C'est-�-dire, sur un syst�me 32bits, sizeof(classe m�re) + 8.

    Et la classe aura donc trois ou quatre vtables :
    • vtable pour les fonctions virtuelles de la classe m�re.
    • vtable pour I1
    • vtable pour I2
    • vtable pour I3
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre �clair�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par d�faut
    Ok merci pour tes �claircissements
    Je vais �viter d�sormais ralentir l'impl�mentation de Pattern et les choses trop complexes en C++. Repasser de JAVA � C++, c'est que du bonheur

  8. #8
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Au fait: C'est une des raisons pourquoi il est fortement d�conseill� d'utiliser des casts C-style en h�ritage multiple : Il faut �tre absolument certain que le cast sera un static_cast et non un reinterpret_cast, car un reinterpret_cast fausserait l'alignement.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Impl�mentation d'interface et g�n�riques
    Par jsebfranck dans le forum Langage
    R�ponses: 2
    Dernier message: 14/10/2007, 12h54
  2. R�ponses: 4
    Dernier message: 02/05/2007, 13h40
  3. R�ponses: 5
    Dernier message: 26/07/2006, 17h01
  4. [Language][1.5]Question interfaces multiple:
    Par FreshVic dans le forum Langage
    R�ponses: 16
    Dernier message: 18/11/2005, 09h41

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