2009-08-20 6 views
1

J'ai la paire de fonctions suivantes:Déterminer l'identité de l'objet d'une référence à une superclasse

void RegisterSink(ISink & Sink) 
void UnregisterSink(ISink & Sink) 

Où ISINK est une classe de base abstraite. En interne, je voudrais stocker des pointeurs vers les puits dans un ensemble std ::. Quand un récepteur n'est pas enregistré, je recherche simplement le pointeur dans mon ensemble, et le supprime. Ma question est, y a-t-il un moyen, que prendre l'adresse du paramètre Sink donnerait des résultats différents, bien que le même objet ait été passé en paramètre. Je sais, que les pointeurs peuvent changer lors de l'insertion dans certains szenarios d'héritage multiple, mais qu'en est-il de cette situation?

Merci d'avance!

Répondre

1

En cas d'héritage multiple, la signification de "même objet" n'est parfois pas évidente. Par exemple, si ISINK est présente deux fois dans la liste des classes de base et n'a pas été hérité de « virtuel », cette situation est possible:

class A {}; 
class B:public A {}; 
class C:public A {}; 
class D:public B,public C {}; 
... 
void f(A *a); 
... 
{ 
    D d; 
    f(static_cast<B*>(&d)); 
    f(static_cast<C*>(&d)); 
} 

Dans ce cas, f va obtenir deux adresses différentes. Que le même objet soit ou non dépend probablement du contexte. Si vous voulez les traiter comme le même objet, dynamic_casting to void * peut aider - il caste à la classe la plus dérivée (quelque chose de virtuel dans A est nécessaire, bien sûr)

8

Comme vous l'avez dit, les adresses de pointeur peuvent changer lors de la conversion entre classes virtuelles avec héritage multiple. Cependant, dans votre cas le type statique est toujours le même: ISink donc la comparaison de deux points de ce type statique est garantie pour être sûre, et donner des résultats reproductibles.

2

Des ajustements de décalage sont effectués en cas d'héritages multiples. IFAIK, ils doivent aboutir à des pointeurs comparant égal et triable avec std :: less <> excepté si votre objet hérite plusieurs fois de ISink alors qu'ISink n'est pas une classe de base virtuelle dans tous les cas.

Questions connexes