Question

Je suis en train de comprendre ce code exemple concernant le navigateur Helper Objects.

A l'intérieur, l'auteur met en œuvre une seule classe qui expose plusieurs interfaces (IObjectWithSite, IDispatch).

Sa fonction QueryInterface effectue les opérations suivantes:

if(riid == IID_IUnknown) *ppv = static_cast<BHO*>(this);
else if(riid == IID_IObjectWithSite) *ppv = static_cast<IObjectWithSite*>(this);
else if (riid == IID_IDispatch) *ppv = static_cast<IDispatch*>(this);

J'ai appris que dans une perspective de C, les pointeurs d'interface ne sont que des pointeurs vers VTables. Donc, je le prends signifie que C ++ est capable de retourner la VTable d'une mise en œuvre en utilisant l'interface static_cast.

Est-ce que cela signifie qu'une classe construite de cette manière a un tas de VTables en mémoire (IObjectWithSite, IDispatch, etc.)? Qu'est-ce que C ++ voir avec les collisions de noms sur les différentes interfaces (ils ont chacun un QueryInterface, AddRef et la fonction Release), puis-je mettre en œuvre des méthodes différentes pour chacun d'entre eux?

Était-ce utile?

La solution

Oui, il existe plusieurs tables de V, une pour chaque interface héritée. Le static_cast <> retourne. Le compilateur fait en sorte que les méthodes courantes dans les interfaces héritées sont partagées, il remplit chaque fente v-table avec un pointeur vers la même fonction. Donc, vous avez seulement besoin d'une mise en œuvre de AddRef, Release, QueryInterface. Tout ce que vous voulez. Rien de tout cela est un accident.

Ce n'est jamais un problème quand un outils de CoClasse multiples interfaces avec la même méthode que vous ne pas veulent donner la même mise en œuvre. La méthode IConnectionPoint :: Advise () est un exemple notoire. Ou était-ce DAdvise ()? Malheureusement, je ne me rappelle pas ce qu'elle contrariait et comment il a été résolu, il était couvert par ATL Internes. Très bon livre btw.

Autres conseils

Dans l'héritage multiple, plusieurs VTables sont disposés en séquence comme format suivant si le pointeur de donnée this (qui pointe vers le premier octet, 01)

[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12]
[Ptr de vtablea] [Ptr de VTableB] [Ptr de VTableC]

En C ++, seulement 1 mise en œuvre sera généré par prototype de fonction dans plusieurs scénarios d'interface. Cependant pour le scénario de succession normale, superclasse aurait peut-être mise en œuvre pré-définies et les enfants qui remplace la fonction leurs VTables pointant vers un contenu différent de celui du parent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top