Quand est-ce que j'utilise un point, une flèche ou un double côlon pour faire référence aux membres d'une classe en C++?
venant d'autres langages dérivés de C (comme Java ou C#) à C++, il est d'abord très confus que C++ ait trois façons de se référer aux membres d'une classe: a::b , a.b , et a->b . Quand dois-je utiliser lequel de ces opérateurs?
(Note: Ceci est censé être une entrée dans Stack Overflow C++ FAQ . Si vous voulez critiquer l'idée de fournir une FAQ sous cette forme, puis le poster sur meta qui a commencé tout ce serait l'endroit pour le faire. Les réponses à cette question sont suivies dans le c++ chatroom , où L'idée de FAQ a commencé en premier lieu, de sorte que votre réponse est très susceptible de se faire lire par ceux qui sont venus avec l'idée.)
2 réponses
les trois opérateurs distincts c++ utilisés pour accéder aux membres d'une classe ou d'un objet de classe, à savoir le double-col :: , le point . , et la flèche -> , sont utilisés pour trois scénarios différents qui sont toujours bien définis. En sachant cela, vous pouvez immédiatement en savoir beaucoup sur a et b simplement en regardant a::b , a.b , ou a->b , respectivement, dans n'importe quel code que vous regardez.
-
a::bn'est utilisé que sibest un membre de la classe (ou de l'espace)a. C'est, dans ce casasera toujours le nom d'une classe (ou de l'espace). -
a.bn'est utilisé que sibest un membre de l'objet (ou la référence à un objet)a. Donc, poura.b,asera toujours un objet réel (ou une référence à un objet) d'une classe. -
a->best, à l'origine, une notation abrégée pour(*a).b. Cependant,->est le seul des opérateurs d'accès aux membres qui peut être surchargé, donc siaest un objet d'une classe qui surchargeoperator->(de tels types courants sont des pointeurs intelligents et des itérateurs), alors la signification est tout ce que le concepteur de classe mis en œuvre. Pour conclure: Aveca->b, siaest un pointeur,bsera un membre de l'objet auquel se réfère le pointeura. Si, cependant,aest un objet d'une classe qui surcharge cet opérateur, alors la fonction d'opérateur surchargéoperator->()est invoquée.
Les petits caractères:
- en C++, les types déclarés comme
class,struct, ouunionsont considérés comme "de type de classe". De sorte que le ci-dessus se réfère à tous les trois d'entre eux. - les références sont, sémantiquement, des alias d'objets, donc j'aurais dû ajouter "ou référence à un pointeur" au #3 aussi. Cependant, j'ai pensé que ce serait plus déroutant qu'utile, puisque les références à des pointeurs (
T*&) sont rarement utilisées. - les opérateurs de points et de flèches peuvent être utilisés pour référez-vous aux membres statiques d'une classe d'un objet, même s'ils ne sont pas membres de l'objet. (Merci à Oli de le souligner!)
suggérant une autre solution pour le point 3 de l'ordre du jour du sbi
" a->b n'est utilisé que si a est un pointeur. C'est un raccourci pour (*a).b , le b membre de l'objet a points de. C++ a deux types de pointeurs, "ordinaire" et des pointeurs intelligents. Pour les pointeurs réguliers tels que A* a , le compilateur implémente -> . Pour les pointeurs intelligents tels que std::shared_ptr<A> a , -> est un membre fonction de la classe shared_ptr .
justification: le public cible de cette FAQ n'écrit pas des pointeurs intelligents. Ils n'ont pas besoin de savoir -> est vraiment appelé operator->() , ou que c'est la seule méthode d'accès membre qui peut être surchargé.