Comment accéder à la méthode protégée dans la classe de base de la classe dérivée?
Voici un exemple de code qui m'agace:
class Base {
protected:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base *b; /* Initialized by constructor, not shown here
Intended to store a pointer on an instance of any derived class of Base */
protected:
virtual void foo() { /* Some implementation */ };
virtual void foo2() {
this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
}
};
Comment avez-vous accès à l'protégé surdéfini fonction?
Merci pour votre aide. :o)
Je ne pense pas que votre mise en œuvre est tout à fait juste. Pourquoi avez-vous un exemple de Base comme une variable de membre? this->b->foo() serait d'essayer d'appeler une méthode virtuelle pure.
Ce programme ne devrait pas compiler. Vous ne peut pas instancier une classe abstraite....Sauf
J'ai omis de précision: la Dérivée::b attribut est conçu pour stocker toutes les instances de classes dérivées à partir de la Base de
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++ appelle des fonctions de membre, pas de méthodes (bien que certaines personnes utiliser ce dernier, mais dans mon expérience que mène juste à des arguments linguistiques), et les concepts sont les mêmes pour les fonctions de membre et de membre des variables, donc: double de Accéder aux membres protégés dans une classe dérivée
Ce programme ne devrait pas compiler. Vous ne peut pas instancier une classe abstraite....Sauf
b
vers une instance d'une autre classe dérivée de Base
.J'ai omis de précision: la Dérivée::b attribut est conçu pour stocker toutes les instances de classes dérivées à partir de la Base de
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++ appelle des fonctions de membre, pas de méthodes (bien que certaines personnes utiliser ce dernier, mais dans mon expérience que mène juste à des arguments linguistiques), et les concepts sont les mêmes pour les fonctions de membre et de membre des variables, donc: double de Accéder aux membres protégés dans une classe dérivée
OriginalL'auteur Bernard Rosset | 2011-01-12
Vous devez vous connecter pour publier un commentaire.
Membres protégés dans une classe de base ne sont accessibles que par l'objet en cours.
Ainsi, vous êtes autorisé à appeler
this->foo()
, mais vous n'êtes pas autorisé à appelerthis->b->foo()
. Ceci est indépendant du fait queDerived
fournit une implémentationfoo
ou pas.La raison derrière cette restriction est qu'il serait autrement très facile à contourner l'accès protégé. Il vous suffit de créer une classe comme
Derived
, et tout à coup vous avez également accès à certaines parties des autres classes (commeOtherDerived
) qui étaient censés être inaccessibles aux étrangers.S'il vous plaît ne pas penser que c'est un trou de sécurité. Modificateurs d'accès n'offrent aucune sécurité, vous avez juste à lire le mémoire de l'emplacement, si vous voulais que les données.
droit, ce n'est pas à propos de "sécurité", mais au lieu de raconter des utilisateurs, que les parties de la classe qu'ils peuvent utiliser et s'appuyer sur (c'est à dire les parties qui ne sont pas des détails de mise en œuvre qui pourraient disparaître/changer à tout moment). bien sûr, ils ne doivent pas lire ce genre de choses, et se faire des acrobaties avec des trucs comme
offsetof
de le faire, mais ce n'est certainement pas au sujet de la sécurité dans le sens d'empêcher physiquement l'accès aux données uniquement à documenter l'usage prévu, de la sémantique et de la stabilité de l'API.OriginalL'auteur Bart van Ingen Schenau
Normalement, vous pouvez le faire en utilisant
Base::foo()
, qui se réfère à la classe de base de l'instance courante.Toutefois, si votre code doit le faire de la manière que vous essayez de le faire et ça n'est pas permis, alors vous aurez besoin soit de faire foo() public ou de faire Dérivée d'un ami de la Base.
OriginalL'auteur Jonathan Wood
Une solution serait de déclarer une statique de la fonction protégée dans
Base
qui redirige l'appel vers le private /protected function (foo
dans l'exemple).Permet de dire:
De cette façon, nous n'avons pas briser l'encapsulation parce que le concepteur de
Base
pouvez faire un choix exprès pour permettre à toutes les classes dérivées pour appelerfoo
les uns sur les autres, tout en évitant de mettrefoo
dans l'interface publique ou explicitement possible de désactiver toutes les sous-classes deBase
en amis.Aussi, cette méthode fonctionne indépendamment de si
foo
est virtuel ou pas, ou si c'est privé ou protégé.Ici est un lien vers une version en cours d'exécution du code ci-dessus et ici une autre version de la même idée avec un peu plus de logique métier.
OriginalL'auteur Clemens Sielaff
C'est un peu fragile, mais avec les classes que vous avez défini ici, n'est ce pas ce travail?
Le reinterpret_cast de points à la VTABLE de l'objet de base, et les appels par le biais de ce les membres de l'accesseur.
OriginalL'auteur Anthony Wieser
Vous appelez de la base de fonctions explicitement du champ d'application de l'opérateur (Base::foo()). Mais dans ce cas, la classe de Base n'est pas de définir foo (c'est virtuelle pure), donc il n'y a effectivement pas de la fonction à exécuter lorsque vous dites
this->b->foo();
puisque b est un pointeur vers la Base et non Dérivé.Bois je comprends ce que vous dites, mais juste d'aller dans le code, il est posté, on dirait qu'il essaye d'instancier une classe de base abstraite (de Base) et appel d'une fonction virtuelle pure (Base::foo()), ce qui n'est pas (GWW et 341008 aussi mentionné ci-dessus).
OriginalL'auteur Gemini14
--- d'où?
Vous pouvez accéder à un membre protégé seulement par héritage (en dehors des méthodes de la même classe). Disons par exemple que vous avez un
class Derived1
qui hérite deDerived
, les objets deDerived1
peut appelerfoo()
.EDIT: Article MSDN sur l'accès protégé spécificateur.
OriginalL'auteur yasouser