Voici un échantillon de code qui m'agace: Comment accéder à la fonction prévisionnelle protégée? p> Merci pour votre aide. : o) p> p>
6 Réponses :
Normalement, vous le feriez en utilisant Toutefois, si votre code doit le faire comme si vous essayez de l'essayer et que vous n'êtes pas autorisé, vous aurez alors besoin de faire du public () public ou de faire dérivé un ami de base. P> Base :: FOO () Code>, qui fait référence à la classe de base de l'instance actuelle. P>
Vous appelez explicitement les fonctions de base avec l'opérateur de la portée (base :: FOO ()). Mais dans ce cas, la classe de base ne définit pas FOO (c'est pur virtuel), il n'y a donc aucune fonction d'exécution lorsque vous dites this-> b-> foo (); code> car b est un pointeur à base et non dérivé. P>
Mais le code de l'OP ne fait pas référence à la classe de base de l'instance actuelle. Il accède à un autre instance, qui est probablement une classe dérivée qui implémente la fonction pure-virtuelle. (Sinon, l'instance n'a pas pu être créée.)
@Jonathan bois Je comprends ce que vous dites, mais juste du code, il est affiché, il semble qu'il tente d'instancier une classe de base abstraite (base) et d'appeler une fonction virtuelle pure (base :: foo ()), qui est un non-non (comme GWW et 341008 également mentionné ci-dessus).
Comment accédez-vous au protégé fonction annulée? p> blockQuote>
--- à partir d'où? P>
Vous pouvez accéder à un membre protégé uniquement via l'héritage (en dehors des méthodes de la même classe). Dites par exemple, vous avez une classe
dérived1 code> qui hérite de
dérivé code>, puis des objets de
dérived1 code> peut appeler
foo () code> . p>
Edit: Article MSDN sur le spécificateur d'accès protégé. P >
Les membres protégés dans une classe de base ne sont accessibles que par l'objet actuel. La raison de cette restriction est qu'il serait très facile de contourner l'accès protégé. Vous venez de créer une classe comme
Ainsi, vous êtes autorisé à appeler this-> foo () code>, mais vous n'êtes pas autorisé à appeler
this-> b-> foo () code>. Ceci est indépendant de savoir si
dérivé code> fournit une implémentation pour
foo code> ou non. P>
dérivé code> et que vous avez tout à coup, vous avez également accès à des parties d'autres classes (comme
autreté injustifié code>) censé être inaccessible aux étrangers. P>
Merci, je comprends maintenant clairement les raisons de la restriction ... ce serait un trou de sécurité ... grand!
S'il vous plaît ne pensez pas à cela comme un trou de sécurité. Les modificateurs d'accès ne fournissent aucune sécurité, vous pouvez simplement lire l'emplacement de la mémoire si vous souhaitiez les données.
Droite, cela ne concerne pas "la sécurité", mais plutôt de dire aux utilisateurs quelles parties de la classe qu'ils peuvent utiliser et s'appuyer sur (c'est-à-dire que les parties ne sont pas des détails de mise en œuvre qui pourraient disparaître / changer à tout moment). Bien sûr, ils ne devraient pas lire ce genre de choses et devront utiliser des acrobatics avec des trucs comme offset de code> pour le faire, mais il ne s'agit certainement pas de la sécurité dans le sens de l'accès physique à l'accès aux données - uniquement de documentation prévue. Utilisation, sémantique et stabilité de l'API.
C'est un peu fragile, mais avec les classes que vous avez définies ici, cela ne fonctionnera pas?
virtual void foo2() { reinterpret_cast<Derived *>(this->b)->foo(); }
Une solution serait de déclarer une fonction protégée statique dans permet dire: p> de cette façon, nous ne casserons pas l'encapsulation car le concepteur de En outre, cette méthode fonctionne, que ici est un lien vers une version exécutée du code ci-dessus et ici < / a> Une autre version de la même idée avec un peu plus de logique commerciale. p> p> base code> qui redirige l'appel à la fonction privée / protégée (
foo code> dans l'exemple).
base code> peut faire un choix explicite pour permettre à toutes les classes dérivées d'appeler
foo code> les uns sur les autres, tout en évitant de mettre
foo code> dans l'interface publique ou de tourner explicitement toutes les sous-classes possibles de
base code> en amis. P>
foo code> soit virtuel ou non, ou si elle est privée ou protégée. p>
Je ne pense pas que votre mise en œuvre ait bien raison. Pourquoi avez-vous une instance de base en tant que variable membre? Ceci-> B-> FOO () tenterait d'appeler une méthode virtuelle pure.
Ce programme ne devrait pas compiler. Vous ne pouvez pas instancier une classe abstraite ... Sauf si
B code> indique une instance d'une autre classe dérivée de
base code>.
J'ai omis de précision: l'attribut dérivé :: B est destiné à stocker une instance de classes dérivées de la base
Voir aussi Stackoverflow.com/questions / 3247671 / ... (c'est à propos des membres au lieu de méthodes, mais ils ne sont pas très différents)
C ++ les appelle les fonctions membres, non pas des méthodes (bien que certaines personnes utilisent ce dernier, mais dans mon expérience qui conduit à des arguments linguistiques), et les concepts sont les mêmes pour les fonctions membres et les variables des membres, donc: duplicata de