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::b
n'est utilisé que sib
est un membre de la classe (ou de l'espace)a
. C'est, dans ce casa
sera toujours le nom d'une classe (ou de l'espace). -
a.b
n'est utilisé que sib
est un membre de l'objet (ou la référence à un objet)a
. Donc, poura.b
,a
sera toujours un objet réel (ou une référence à un objet) d'une classe. -
a->b
est, à 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 sia
est 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
, sia
est un pointeur,b
sera un membre de l'objet auquel se réfère le pointeura
. Si, cependant,a
est 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
, ouunion
sont 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é.