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.)

222
demandé sur Community 2011-02-13 17:11:22

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.

  1. a::b n'est utilisé que si b est un membre de la classe (ou de l'espace) a . C'est, dans ce cas a sera toujours le nom d'une classe (ou de l'espace).

  2. a.b n'est utilisé que si b est un membre de l'objet (ou la référence à un objet) a . Donc, pour a.b , a sera toujours un objet réel (ou une référence à un objet) d'une classe.

  3. 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 si a est un objet d'une classe qui surcharge operator-> (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: Avec a->b , si a est un pointeur, b sera un membre de l'objet auquel se réfère le pointeur a . 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 , ou union 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!)
223
répondu sbi 2017-09-26 17:11:56

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é.

31
répondu MSalters 2014-05-04 07:58:26