2010-09-18 8 views
2
struct A { 
protected: 
    int y; 
public: 
    int z; 
}; 

struct F : A { 
public: 
    using A::y; 
private: 
    using A::z; 
}; 

int main() { 
    F obj_F; 
    obj_F.y = 9; 
    obj_F.z = 10; 
} 

Source: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=/com.ibm.vacpp7a.doc/language/ref/clrc14cplr135.htmAccès membres dans Hiérarchie d'héritage - C++

Dans le code ci-dessus obj_F.z = 10; - est autorisé. Explication: L'accès du membre z est toujours public. La déclaration privée utilisant A :: z n'a aucun effet sur l'accès de z.

Quelqu'un peut-il me dire, si z, qui est déclaré comme privé, est accessible à l'extérieur, alors quelle est la signification de ce privé? Qu'est ce que ça fait?

Merci

-Saiyasodharan

+1

erreur C2248: 'F :: z': impossible d'accéder au membre privé déclaré dans la classe 'F' – bjskishore123

+1

En g ++: * erreur: 'int A :: z' est inaccessible * –

+0

a obtenu la même erreur dans VC++ 10 .. bien que ce soit correct selon les standards, il est incorrect dans MS VC++ il semble – saiy2k

Répondre

3

Le code est valide selon la norme - voir cette règle standard, que je n'ai pas eu à l'esprit quand je répondais avant

A member m is accessible when named in class N if

  • [...], or
  • there exists a base class B of N that is accessible at the point of reference, and m is accessible when named in class B.

Cela vaut tout à fait à votre code, et donc l'accès est valide ... Il semble que le but principal de cette règle est de permettre aux déclarations d'amis de la base de s'appliquer aux membres hérités, mais cela s'applique également à ce cas.


(Ne tenez pas compte des parties de ce qui disent que le code est invalide - Il est valide comme expliqué ci-dessus Cette partie est une ancienne version de ma réponse, gardé ici pour servir des informations générales.)

Non, ce code est invalide. Voilà pourquoi les équivalents « accès » déclarations sont appelées de cette façon (ceux-ci sont déconseillés bien)

struct F : A { 
public: 
    A::y; 
private: 
    A::z; 
}; 

Ceux-ci sont appelés précisément « accès déclarations » parce que ils peuvent modifier l'accès ...Dans votre exemple, la classe de dénomination est F et z en tant que membre de F est privée car la déclaration d'utilisation a fait modifier le niveau d'accès du nom.

+1

mon doute cleard .. thx :-) – saiy2k

+0

Je ne sais pas pourquoi Charles a supprimé sa réponse (bien que le premier et dernier paragraphe de sa réponse étaient corrects). 'Le code est valide selon la norme'. Qu'est-ce qui rend le code valide? Il est encore mal formé. Est-ce différent de la validité du code? –

+0

@Prasoon le code est valide - voir le texte que j'ai cité de la norme. J'ai juste testé différents compilateurs pour voir comment ils se conforment à cette bizarrerie, et pour moi, seul Comeau l'accepte. J'ai envoyé un PR à clang: http://llvm.org/bugs/show_bug.cgi?id=8178. @Charles a également fait un bon point sur le contourner en disant 'obj_F.A :: z'. –

-2

F hérite d'un privé. Vous ne pouvez donc accéder à aucun membre public de A si vous utilisez une définition de F en dehors de F. Parce que F ne définit aucun membre, F est fondamentalement inutile.

Si F hérite d'un public (ie :)

struct F : public A {}; 

Ensuite, vous pouvez maintenant utiliser membre public A. de sorte que vous pouvez écrire obj_F.z

Si vous avez une variable z qui est public dans un privé et en F, à savoir:

struct A { public: int z; }; 
struct F : public A { private: int z; }; 

alors les deux z sont en fait deux variables différentes. Ce n'est pas ce que tu veux.

également, comme Andre Holzner a dit, votre déclaration using sont inutiles ici.

Généralement, vous ne pouvez pas, dans un langage de programmation d'objet, restreindre la portée d'un membre dans une sous-classe héritée du public. Soit la définition de classe ne compilera pas, n'obéira pas, ou créera un autre membre avec le même nom. Ceci parce que votre F n'est pas compatible avec le code qui traite d'un A ou d'une sous-classe de celui-ci.

+1

'F hérite de A en privé '. -1 pour ça. 'F' et' A' sont des structures (pas des classes). –