C++: Pourquoi faut-il privé des fonctions-ils être déclarés?
Pourquoi les classes en C++ doivent déclarer leurs fonctions privées? Elle a de réelles raisons techniques (quel est son rôle au moment de la compilation) ou est-ce simplement pour des raisons de cohérence?
- Demandez-vous pourquoi les fonctions elles-mêmes doivent être déclarés, ou demandez-vous pourquoi vous avez à dire
private
pour ces fonctions? - Je pense que la première.
- 1er. Je ne sais pas pourquoi les autres classes, y compris l'en-tête doivent savoir au sujet de ses fonctions privées
- ils n'en ont pas. C'est l'info pour la classe elle-même - c'est à dire la classe sait que
foo
est membre et a accès à d'autres membres. private
etvirtual
sont orthogonaux concepts. Le fait qu'une fonction estprivate
n'implique pas qu'il n'est pasvirtual
(comme une question de fait, il y a tout un idiome d'avoir seulementprivate
virtual
etpublic
non virtuelle fonctions de membre), donc oui, la présence d'affecter la vtable.- bon point. En fait je ne savais pas privé virtuel de fonctions peut être redéfinie dans les classes enfant et ont leurs classes de base d'appel de la nouvelle version sans exposer callability(est-ce encore un mot?)
- Le mot que vous voulez, c'est "l'accessibilité".
Vous devez vous connecter pour publier un commentaire.
Si vous pensez à ce sujet, ce qui est similaire à la déclaration de certaines fonctions
static
dans un fichier. Il n'est pas visible de l'extérieur, mais il est important que le compilateur lui-même. Le compilateur veut savoir la signature de la fonction avant de l'utiliser. C'est pourquoi vous déclarer des fonctions en premier lieu. Rappelez-vous que les compilateurs C++ sont un seul passage, ce qui signifie que tout doit être déclaré avant d'être utilisé.1À partir du programmeur point de vue, en déclarant privé des fonctions n'est pas encore complètement inutile. Imaginez 2 classes, dont l'une est la
friend
de l'autre. Le friendzoned classe2 aurait besoin de savoir comment les soldats de la classe ressembler, (Cette discussion est d'obtenir bizarre) sinon ils ne peuvent pas l'utiliser.Pourquoi exactement C++ a été conçu de cette façon, je voudrais tout d'abord dire qu'il y a de la raison historique: le fait que vous ne pouvez pas couper un struct en C, a été adopté par le C++, donc vous ne pouvez pas couper une classe (et adoptée par d'autres langues ramifié en C++, trop). J'avais aussi pense que c'est le sujet de la simplicité: Imaginez combien il serait difficile de concevoir une méthode de compilation dans laquelle vous pouvez diviser la classe parmi les différents fichiers d'en-tête, laissez vos fichiers source du savoir, et d'empêcher les autres d'ajouter des choses à votre classe.
Une dernière remarque est que,
private
fonctions peut affecter la vtable de taille. C'est, si elles sontvirtual
.1 en Fait, pas tout à fait. Si vous avez des fonctions inline dans la classe, ils peuvent se référer à des fonctions plus tard définies dans la même classe. Mais probablement que l'idée a commencé à partir d'une seule passe et cette exception a ajouté plus tard pour elle.
2 C'est inline fonctions de membre en particulier.
void *internal;
, mais c'est juste une solution de contournement).struct
en C, a été adopté par le C++, donc vous ne pouvez pas couper lesclass
(et adoptée par d'autres langues ramifié en C++, trop), je suppose que c'est à propos de la simplicité. Imaginez combien il serait difficile de concevoir un plan de sorte que vous pouvez diviser la classe parmi les différents fichiers d'en-tête, que tout le monde sache à ce sujet, et d'empêcher les autres d'ajouter des choses à votre classe.Vous devez déclarer tous les membres dans la définition de la classe elle-même, de sorte que le compilateur sait quelles fonctions sont permis à être membres. Sinon, un second programmeur pourrait (accidentellement?) venez et ajouter des membres, de faire des erreurs, et de violer l'objet de garanties, provoquant un comportement indéfini et/ou des plantages aléatoires.
Il y a une combinaison de préoccupations, mais:
Donc:
De la POV de pratique de la compatibilité binaire: comme David dit dans un commentaire, privé
virtual
fonctions affectent la taille et la disposition de la vtable de cette classe et de toutes les classes qui l'utilisent comme base. Ainsi, le compilateur a besoin de les connaître, même lors de la compilation de code qui ne peut pas les appeler.Pourrait C++ ont été inventé différemment, pour permettre à l' .fichier cpp de rouvrir la classe et les ajouter certains types de membres supplémentaires fonctions, avec la mise en œuvre doivent veiller à ne pas rompre la compatibilité binaire? Pourrait une définition de la règle est assouplie, afin de permettre des définitions qui diffèrent à certains égards? Par exemple, les fonctions membres statiques et non virtuelle non-fonctions membres statiques.
Probablement oui pour les deux. Je ne pense pas qu'il n'y a aucun obstacle technique, bien que l'ODR est très strict sur ce qui rend une définition de "différent" (et par conséquent est très généreux pour les implémentations permettant binaire incompatibilités entre très similaire à la recherche de définitions). Je pense que le texte à introduire ce genre d'exception à la règle serait complexe.
En fin de compte, il pourrait en venir à la, "les concepteurs ont voulu de cette façon", ou il pourrait être que quelqu'un l'a essayé et a rencontré un obstacle que je n'ai pas pensé.
private
sera alors tout simplement pas de fuite en dehors de la définition de module, et le compilateur ne peut pas toujours tout savoir.[temp.expl.spec]
"explicite d'Une spécialisation de l'un quelconque des éléments suivants: (...) — membre de modèle de classe d'une classe ou d'un modèle de classe — fonction membre template d'une classe ou d'un modèle de classe peut être déclarée par une déclaration (...)" "explicite la spécialisation doit être déclarée dans un espace de noms en joignant spécialisées modèle".Le niveau d'accès n'a pas d'incidence sur la visibilité. Les fonctions privées sont visibles à un code externe et peut être sélectionné par la résolution de surcharge (qui pourrait alors entraîner un accès violoation erreur):
Imaginer la confusion quand cela fonctionne:
Mais de le changer pour le premier code de résolution de surcharge pour sélectionner une fonction différente. Et que dire de l'exemple suivant?
Ou voici un autre exemple de ce qui va pas:
a.F(1)
de la compilation en code client, et si il est ajouté que dansA.cpp
alors qu'elle n'affecte pas de code client, mais n'affecte pas la .rpc. C'est déjà comment les espaces de travail (si vous ajoutez plus de surcharges, ils peuvent être sélectionnés). Il y a une certaine complexité requis, par exemple ce qui se passe avec les deux en phase de recherche.= delete
de la syntaxe.L'une des raisons est qu'en C++ les amis peuvent accéder à vos soldats. Pour les amis pour y accéder, les amis de la connaître.
friend
s.Membres privés d'une classe sont toujours membres de la classe, de sorte qu'ils doivent être déclarés, comme la mise en œuvre d'autres membres du public peuvent dépendre du fait que la méthode privée. Déclarant permettra au compilateur de comprendre un appel à cette fonction comme un appel de fonction membre.
Si vous avez une méthode n'est utilisée int la
.cpp
fichier et ne dépend pas de l'accès direct à d'autres membres privés de la classe, envisager de passer à un anonyme, un espace de noms. Ensuite, il n'a pas besoin d'être déclarée dans le fichier d'en-tête.Il ya un couple de raisons pourquoi les fonctions privées doivent être déclarés.
Première Erreur De Compilation Des Contrôles
le point de modificateurs d'accès est d'attraper certaines classes (no pun intended) des erreurs de programmation au moment de la compilation. Privé des fonctions sont des fonctions qui, si quelqu'un appelé de l'extérieur de la classe, ce serait un bug, et vous voulez savoir à ce sujet dès que possible.
Deuxième Casting et de l'Héritage
Prises à partir de la norme C++:
3 [ Note: Un membre privé de la classe de base peut être inaccessible hérité d'un nom de membre, mais accessible directement. Parce que les règles sur le pointeur de conversions (4.10) et les conversions explicites (5.4), une conversion d'un pointeur vers une classe dérivée vers un pointeur vers un inaccessible de la classe de base peut être mal formé si une conversion implicite est utilisé, mais bien formé si un cast explicite est utilisé.
3ème Amis
Amis montrent les uns des autres il y a des soldats. Une méthode privée ne peut être appel par une autre classe qui est un ami.
4ème Générale de l'esprit et la Bonne Conception
Jamais travaillé sur un projet avec une autre de 100 développeurs. Avoir un standard et un ensemble de règle permet de maintenir maintenable. déclarer quelque chose de privé, a un sens précis à chacun dans le groupe.
Également ce flux en bonne OO principes de conception. Ce que pour exposer et ce n'est pas