Question

En général, la déclaration « à l'aide » est utilisé pour mettre en portée des fonctions membres des classes de base qui seraient autrement cachés. De ce point de vue, il est seulement un mécanisme permettant de rendre l'information accessible plus pratique à utiliser.
Cependant: la déclaration « à l'aide » peut également être utilisé pour modifier les contraintes d'accès (non seulement pour les fonctions mais aussi pour les attributs). Par exemple:

class C{
public:
  int a;
  void g(){ cout << "C:g()\n"; }
  C() : a(0){}
};

class D : public C{
private:
  using C::a;
  using C::g;
public:
  D() { a = 1; }
};

int main(void){
  D d;
  cout << d.a << endl;  //error: a is inaccessible
  C *cp = &d;
  cout << cp->a << endl; //works
  d.g();  //error: g is inaccessible
  cp->g();  //works
  return 0;
}

Je pense que cette limitation de l'accès dans la classe dérivée est en réalité d'aucune utilité, car vous pouvez toujours accéder à g () et d'un pointeur vers la classe de base. Donc, should't y ait au moins une sorte d'avertissement du compilateur? Ou serait-il pas été encore mieux d'interdire cette limitation de l'accès par une classe dérivée? La déclaration à l'aide n'est pas la seule possibilité d'ajouter des contraintes d'accès. Il pourrait également se faire via la suppression d'un fonction de la classe de base une qu'il plaçant dans une section avec plus de contraintes d'accès. Y a-t-il des exemples raisonnables où il est en effet nessecary de limiter l'accès de telle manière? Sinon, je ne vois pas pourquoi il devrait être autorisé.

Et une autre chose: au moins avec g ++ le même code compile bien sans le mot « utilisant ». Cela signifie que pour l'exemple ci-dessus: il est possible d'écrire C :: a; et C :: g; au lieu d'utiliser C :: a; en utilisant C :: g; Est-ce que le premier raccourci pour celui-ci ou sont-il des différences subtiles?

// EDIT:
donc de la discussion et des réponses ci-dessous ma conclusion serait:
- il est permis de limiter les contraintes d'accès dans les classes dérivées héritage public
- il existe des exemples utiles où il pourrait être utilisé
- son utilisation peut causer des problèmes en combinaison avec des modèles (par exemple une classe dérivée ne pouvait pas être un paramètre valide pour une classe template / fonctionner plus bien que sa base est)
- une conception du langage propre ne devrait pas permettre une telle utilisation
- compilateur pourrait émettre au moins une sorte d'avertissement

Était-ce utile?

La solution

En ce qui concerne votre déclaration sans using: Ceux-ci sont appelés « déclarations d'accès », et sont déconseillés. Voici le texte de la norme, de 11.3/1:

  

L'accès d'un membre d'une classe de base peut être modifiée dans la classe dérivée en mentionnant son id-qualifié   la déclaration de classe dérivée. Une telle mention est appelé une déclaration d'accès. L'effet d'une déclaration d'accès qualified-id ; est défini comme équivalent à la déclaration using qualified-id ; [Note: les déclarations d'accès sont déconseillés; membres en utilisant les déclarations solennelles (7.3.3) fournir un meilleur moyen de faire les mêmes choses. Dans les versions antérieures du langage C ++, les déclarations d'accès étaient plus limitées; ils ont été généralisés et ont fait équivalent à en utilisant les déclarations solennelles - la note de fin]

Je dirais que le plus souvent ce n'est pas bon de changer publics membres aux membres privé ou protégés dans la classe dérivée, parce que cela violer le principe de substitution: vous savez une classe de base a des fonctions, et si vous lancez une alors classe dérivée vous attendre ces fonctions à appelable aussi, parce que la classe dérivée est-a base. Et comme vous l'avez mentionné, cet invariant est déjà appliquée de toute façon par la langue permettant de convertir (qui travaille implicitement!) À une référence de classe de base, ou qualifier le nom de la fonction, puis d'appeler la fonction (alors publique).

Si vous voulez interdire à quelqu'un d'appeler un ensemble de fonctions de la base, alors je pense que ce que le confinement laisse deviner (ou dans de rares cas, l'héritage privé) est une meilleure idée.

Autres conseils

Alors que la déclaration à l'aide que vous montriez fournit un mécanisme pour changer le niveau d'accès (mais seulement vers le bas), ce n'est pas l'utilisation principale de celui-ci dans un tel contexte. Un contexte à l'aide, il est principalement destiné à permettre l'accès aux fonctions qui seraient autrement ombrées de la classe de base en raison de la mécanique du langage. Par exemple.

class A {
public:
   void A();
   void B();
};

class B {
public:
   using A::B;
   void B(int); //This would shadow A::B if not for a using declaration
};

La déclaration

using C::a

apporte « un » à la portée de dénomination locale afin que vous pouvez ensuite utiliser « un » à refere à « C :: un »; depuis que, « C :: a » et « a » sont interchangeables aussi longtemps que vous ne déclarez pas une variable locale avec le nom « a ».

La déclaration ne change pas les droits d'accès; vous pouvez accéder à « un » dans la sous-classe seulement parce que « a » est pas privé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top