2009-10-26 14 views
9

J'ai une ancienne base de code ici, où ils ont utilisé des variables membres protégés. Que ce soit ou non une bonne idée peut être discutée. Cependant, le code doit avoir été compilé correctement avec gcc3. J'ai un il y a quelque chose fait avec xAccès protégé membre d'une classe dans une classe dérivée

template <class Something> void Bar<Something>::cleanup() { 
    doSomeThingCleanUpLike (x); 
} 

Bar modèle de classe dérivée qui utilise membre protégé x du modèle de classe Foo comme si

template <class Something> class Foo { 
public: 
// stuff... 
protected: 
    some::type x; 
} 

template <class Something> Bar : Foo<Something> { 
public: 
    void cleanup(); 
} 

Et dans la déclaration de la méthode de nettoyage() Cela ne ne fonctionne pas avec gcc4, bien qu'il aurait dû fonctionner avec gcc3. Cela fonctionne quand je le change en

doSomeThingCleanUpLike (this->x); 

Pourquoi est-ce le cas?

+1

Le terme «classe de modèle» est souvent source de confusion. Le terme correct est "modèle de classe", car la chose est un modèle pour les classes. Ce n'est pas une classe. Je voudrais éditer votre question mais c'est probablement l'une des raisons pour lesquelles vous êtes confus. – MSalters

+1

Votre définition de fonction de "nettoyage" n'est pas conforme. manque le type de retour et les arguments de modèle pour "Bar". Bien sûr que c'est comme ça dans ton code? –

+0

Merci litb. Je l'ai changé. le niveau de caféine n'était pas assez élevé pour le repérer. Également changé pour "class template". Si son modèle de classe ou de classe ne devrait pas affecter le problème. Le terme est juste utilisé officieusement beaucoup. – GeeF

Répondre

13

L'expression x utilisée dans la classe dérivée est, selon les règles de la norme, indépendante de tout paramètre de modèle de la classe dérivée. Pour cette raison, la recherche s'effectue dans le contexte de la définition du modèle et non au moment de l'utilisation/de l'instanciation. Même si la classe de base modèle du modèle semble être visible, comme il s'agit d'une classe modèle, l'instanciation particulière qui pourrait être utilisée peut impliquer des modèles spécialisés. La définition de modèle de classe de base ne peut donc pas être utilisée pour la recherche de noms. En remplaçant l'expression par this->x, vous en définissez une expression dépendante (this dans un modèle de classe dépend toujours des paramètres de modèle). Cela signifie que la recherche se produira dans le contexte d'instanciation à quel point la classe de base est entièrement connue et ses membres sont visibles.

+0

+1 en utilisant le terme approprié: * dépendants */* noms non dépendants *. –

6

Lorsque vous définissez le modèle dérivé, le compilateur ne connait que le nom de la classe du modèle de base mais pas ses détails, de sorte que le compilateur ne sait pas que la classe dérivée a un membre hérité. Afin de dire au compilateur de l'existence du membre, utilisez this->, tout comme vous l'avez fait. En réalité, il s'agit d'un doublon de this question.

+1

Il est important de noter que l'ajout de 'this->' n'est pas un rituel, mais un moyen de convertir un nom non dépendant en un nom dépendant. Voir la réponse de Charles. –

+0

Bonne prise, cette question avait un mauvais titre. Fixé maintenant – MSalters