[Résolu] typeid

typeid [Résolu] - C++ - Programmation

Marsh Posté le 09-04-2006 à 19:44:55    

Voilà mon pb, je précise que je commence dans l'utilisation des templates ...
 

Code :
  1. template <class Q>
  2. STDMETHODIMP QueryInterface(Q **pp)
  3. {
  4.  // Interface Dispatcher
  5.  if ( pp == NULL) return E_POINTER;
  6.  ATLASSERT(*pp == NULL);
  7.  if (  typeid(Q) == typeid(IChannel))
  8.   return CBChannel::QueryInterface(pp);
  9.  else if (typeid(Q) == typeid(CServices))
  10.   return m_CParser.QueryInterface(pp);
  11.  return E_NOINTERFACE;
  12. }


 
Et lorsque je déclare :
 

Code :
  1. // Query IDVBChannel Interface to Channel Event
  2. CServices * pIDVBChannel(NULL);
  3. if (FAILED(hr = m_ChannelEvent.QueryInterface(&pIDVBChannel))) {
  4.  _LOG(_T("Failed to QI CServices from Channel Event : %0X" ), hr);
  5. }


 
A la compilation j'ai l'erreur :
 
e:\Dev\Src\Tnt\Ktv3_new\K!TV_02042006_1925\Sources\dvbt\DVBTChannelEvent.h(149) : error C2664: 'CBChannel::QueryInterface' : impossible de convertir le paramètre 1 de 'CServices ** ' en 'IChannel ** '
        Les types pointés n'ont aucun rapport entre eux ; conversion nécessitant reinterpret_cast, cast de style C ou cast de style fonction
        e:\Dev\Src\Tnt\Ktv3_new\K!TV_02042006_1925\Sources\dvbt\DVBTChannel.cpp(361) : voir la référence à l'instanciation du modèle de fonction 'HRESULT CDVBTChannelEvent::QueryInterface<CServices>(Q ** )' en cours de compilation
        with
        [
            Q=CServices
        ]
 
Je ne pige pas pourquoi l'erreur s'applique au type IChannel alors que j'utilise le type CServices, comme si
typeid ne fonctionnait pas comme je le conçois  !?
 
Merci


Message édité par cricri_ le 10-04-2006 à 15:19:35
Reply

Marsh Posté le 09-04-2006 à 19:44:55   

Reply

Marsh Posté le 09-04-2006 à 21:32:29    

A lire le message d'erreur, tu veux passer un CServices** à :
(void?) CBChannel::QueryInterface( IChannel ** );    ( ligne 9 )
 
Tu devrais voir le problème, non ?

Reply

Marsh Posté le 09-04-2006 à 22:35:38    

ne jamais utiliser typeid comme ça. utilise dynamic_cast

Reply

Marsh Posté le 09-04-2006 à 22:36:37    

d'ailleur ici je vois pas trop l'interet du template ...

Reply

Marsh Posté le 10-04-2006 à 08:46:44    

@++fab : justement ça ne devrait pas être possible si le typeid faisait son boulot, et cela devrait correspondre au 2ème cas :  
 
       else if (typeid(Q) == typeid(CServices))
 
@Kangol : comment ferais-tu sans Template ?
 
@Taz : ok, je vais essayer avec dynamic_cast, mais dans mon esprit c'était pour des classes dérivées.
 
En tout ca ce n'est pas très clair pour moi ce typeid et son utilisation ...
 
Merci.

Reply

Marsh Posté le 10-04-2006 à 09:48:45    

typeid fonctionne au runtime, quand tu écrit:
  if (     typeid(Q) == typeid(IChannel))
tu n'empêche pas le compilo d'essayer de compiler
            return CBChannel::QueryInterface(pp);
avec le mauvais type.

Reply

Marsh Posté le 10-04-2006 à 10:04:26    

cricri_ a écrit :


@Taz : ok, je vais essayer avec dynamic_cast, mais dans mon esprit c'était pour des classes dérivées.


oh putain, j'avais pas vu ton, truc, tu compares statiquement des types ... ouch !

Reply

Marsh Posté le 10-04-2006 à 10:15:53    

ok, je crois que je commence à comprendre mon erreur ...
Donc c'est vraiment le dynamic_cast que je dois utiliser dans ce cas.

Reply

Marsh Posté le 10-04-2006 à 10:19:21    

justement nom, le typage est satique, il suffit de specialisé ton template par exemple

Reply

Marsh Posté le 10-04-2006 à 10:41:08    

> justement nom, le typage est satique, il suffit de specialisé ton template par exemple
 
oui, mais l'une des deux lignes typeid()=typeid() est forcément fausse, même si le template lorsqu'il est instancié pourrait permettre une optimisation.

Reply

Marsh Posté le 10-04-2006 à 10:41:08   

Reply

Marsh Posté le 10-04-2006 à 11:30:46    

Si je comprends bien il n'y a pas de solution "simple" à mon problème ?

Reply

Marsh Posté le 10-04-2006 à 11:32:12    

si, une fonction virtuelle!

Reply

Marsh Posté le 10-04-2006 à 11:56:15    

Pour l'instant je ne vois pas trop comment, mais je vais essayer de cogiter là dessus.
Merci

Reply

Marsh Posté le 10-04-2006 à 12:04:10    

Tu fait une classe de base avec la fonction virtuelle:
virtual CService* queryInterface()=0;
Ensuite tu dérive cette classe vers les classes que tu comptes utiliser avec ton template, et tu y réimplémente queryInterface().

Reply

Marsh Posté le 10-04-2006 à 14:19:26    

Je ne vois pas trop là, car si l'on regarde le 1er message, j'ai 2 interfaces possibles à récupérer : CServices ou IChannel, qui n'ont en fait rien en commun, ce ne sont pas des classes dérivées d'une même classe parente.
 
Il est vrai que je n'ai probablement pas été suffisamment précis à ce niveau ...
Merci


Message édité par cricri_ le 10-04-2006 à 14:20:24
Reply

Marsh Posté le 10-04-2006 à 14:26:30    

tu specialises ton template ou sans template tu fais des surcharges, mais ca revient au meme
 
apres je ne dis pas qu'il n'y a pas de probleme de conception

Reply

Marsh Posté le 10-04-2006 à 14:59:28    

STDMETHODIMP QueryInterface(IChannel **pp)
{
....
}
 
STDMETHODIMP QueryInterface(CServices **pp)
{
....
}
 
:??:
 

Reply

Marsh Posté le 10-04-2006 à 15:04:32    

Ah ben vi tout simplement ...  :pt1cable:  
Merci  :jap:  

Reply

Marsh Posté le 10-04-2006 à 15:42:43    

:D (en fait c'est ce que tout le monde suggérait depuis le début...)

Reply

Marsh Posté le 10-04-2006 à 16:35:18    

vi, j'ai fait le boolay sur ce coup là ...  :whistle:  
Je ne sais pas pourquoi, enfin si, je voulais faire ça de la même façon qu'on récupère les interface en DShow ...  :??:  

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed