2010-12-02 26 views
8

Considérons que j'ai une classe Foo (qui n'a pas son opérateur & surchargé) est l'adresse obtenue de l'opérateur & de cette classe garanti pour avoir la même valeur que son pointeur this?Est-ce que la valeur C++ est garantie?

Dans le code ci-dessous est equalPointer garanti pour renvoyer vrai? Existe-t-il des cas où il peut renvoyer false (par exemple, en cas d'héritage multiple)?

class Foo 
{ 
    bool equalPointer(const Foo * f} { return f==this; } 
} 
Foo f; 
f.equalPointer(&f); 

Répondre

3

La question est l'une des mise en page de la mémoire. La norme ne garantit pas beaucoup sur la mise en page de mémoire, en particulier, il ne garantit pas que sans décalage existe entre un dérivé et une classe de base ...

Par exemple:

class Foo: public boost::noncopyable 
{ 
public: 
    virtual ~Foo(); 
}; 

Parce que boost::noncopyable n » t ont une méthode virtual, en gcc (void*)(Foo*)&f et (void*)(boost::noncopyable*)&f auront des valeurs différentes.

Mais cela n'a pas beaucoup d'importance en pratique, car le compilateur effectuera les ajustements nécessaires. En d'autres termes, si vous ne comparez que Foo*, vous devriez être bon et dandy ...

... À part que l'héritage multiple peut casser ceci, s'il y a plusieurs sous-objets Foo dans votre hiérarchie.

D'autre part, vous devriez être dans l'un des deux cas:

  • soit il n'y a pas de hiérarchie (pas virtuel) et vous pouvez comparer l'adresse d'objets tout comme
  • ou il y a une hiérarchie (et une méthode virtuelle) et vous utilisez dynamic_cast<void*>(&f) pour obtenir l'adresse de l'objet complet.

Par conséquent, en tant que méthode de modèle, cela donnerait:

template <typename T, typename U> 
bool have_same_dynamic_location(T const& t, U const& u) 
{ 
    return dynamic_cast<void*>(&t) == dynamic_cast<void*>(&u); 
} 

(ce qui est valable uniquement si les deux T et U ont des méthodes virtuelles)

+0

+1 Oui !!! Voir aussi cette question http://stackoverflow.com/q/1742848/57428 – sharptooth

2

Avec le code en question? Oui.

Y a-t-il des constructions dans lesquelles ce n'est pas si vrai? Aussi oui.

Mais oui, un pointeur vers une instance de classe X sera toujours égal au pointeur 'this' dans la classe X. On ne peut pas en dire autant de ses classes de base ou des classes dérivées.

+1

Hmm. Que se passe-t-il lorsque la fonction est définie comme 'template bool equalPointer (T const * f)' et appelée 'f.equalPointer (& f)'? Est-ce que 'f == this' est garanti maintenant? Correction offset ne devrait pas se produire alors, non? –

2

Oui, c'est.

Le pointeur de f est le même, et il est transmis à f::equalPointer ...