Venant d'autres langages dérivés du C (comme Java ou C #) en C++, il est au début très déroutant que C++ dispose de trois façons de faire référence aux membres d'une classe: a::b
, a.b
et a->b
. Quand dois-je utiliser lequel de ces opérateurs?
(Remarque: il s'agit d'une entrée dans FAQ C++ de Stack Overflow . Si vous souhaitez critiquer l'idée de fournir une FAQ dans ce formulaire , alors la publication sur la méta qui a commencé tout cela serait l'endroit pour le faire. Les réponses à cette question sont surveillées dans le C++ chatroom , où la FAQ L’idée a commencé au début, alors votre réponse sera très probablement lue par ceux qui l’ont proposée.)
Les trois opérateurs distincts utilisés par C++ pour accéder aux membres d'une classe ou d'un objet de classe, à savoir le double signe deux-points ::
, Le point .
Et la flèche ->
, Sont utilisés pour trois scénarios différents qui sont toujours bien définis. Sachant cela, vous en savez immédiatement 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 si b
est membre de la classe (ou de l'espace de noms) a
. C'est-à-dire que, dans ce cas, a
sera toujours le nom d'une classe (ou d'un espace de noms).
a.b
N'est utilisé que si b
est un membre de l'objet (ou une 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.
a->b
Est, à l'origine, une notation abrégée pour (*a).b
. Cependant, ->
Est le seul des opérateurs d'accès membre pouvant être surchargé. Par conséquent, si a
est un objet d'une classe qui surcharge operator->
(Ces types courants sont des pointeurs intelligents.) et itérateurs), la signification est celle que le concepteur de classe a implémentée. Pour conclure: Avec a->b
, Si a
est un pointeur, b
sera un membre de l'objet auquel le pointeur a
fait référence. Si, toutefois, a
est un objet d'une classe qui surcharge cet opérateur, la fonction opérateur surchargée operator->()
est invoquée.
Les petits caractères:
class
, struct
ou union
sont considérés comme "de type classe". Donc, ce qui précède fait référence aux trois d'entre eux.T*&
) Sont rarement utilisés.Proposer une alternative au point 3 de sbi
a->b
N'est utilisé que si a
est un pointeur. C'est un raccourci pour (*a).b
, Le membre b
de l'objet sur lequel a
pointe. C++ a deux types de pointeurs, les pointeurs "normaux" et les pointeurs intelligents. Pour les pointeurs ordinaires tels que A* a
, Le compilateur implémente ->
. Pour les pointeurs intelligents tels que std::shared_ptr<A> a
, ->
Est une fonction membre de la classe shared_ptr
.
Justification: le public cible de ceci FAQ n'écrit pas de pointeurs intelligents. Ils n'ont pas besoin de savoir que ->
S'appelle vraiment operator->()
, ou que c'est la seule méthode d'accès membre qui peut être surchargée.
#include <iostream>
#include <string>
using namespace std;
class Human {
private:
int age;
public:
string name;
Human(int humanAge, string humanName)
: age(humanAge), name(std::move(humanName)) {}
void DoSomething() {
cout << age << endl;
}
static void DisplayAge(const Human& person) {
cout << person.age << endl;
}
// ...
};
int main() {
// Usage of Dot(.)
Human firstMan(13, "Jim"); // firstMan is an instance of class Human
cout << firstMan.name << endl; // accessing member attributes
firstMan.DoSomething(); // accessing member functions
// Usage of Pointer Operator (->)
Human* secondMan = new Human(24, "Tom");
cout << secondMan->name << endl; // accessing member attributes
secondMan->DoSomething(); // accessing member functions
cout << (*secondMan).name << endl; // accessing member attributes
(*secondMan).DoSomething(); // accessing member functions
// Usage of Double Colon (::)
Human::DisplayAge(firstMan);
firstMan.DisplayAge(firstMan); // ok but not recommended
secondMan->DisplayAge(firstMan); // ok but not recommended
delete(secondMan);
return 0;
}
Dans l'exemple de codage ci-dessus, nous voyons que:
* Accès aux membres (attributs et fonctions) à partir d'une instance (ou objet) à l'aide de l'opérateur point (.
)
* Accès aux membres (attributs et fonctions) depuis un pointeur sur un objet (ou créé par new
) à l’aide de l’opérateur de pointeur (->
)
* Accès aux fonctions membres statiques à partir de la classe elle-même sans avoir un objet en tant que descripteur utilisant le double signe deux-points (::
). [Remarque: vous pouvez également appeler la fonction de membre statique à partir d'une instance avec .
ou ->
qui n'est pas recommandé]