Duplicate possible:
Quand dois-je utiliser un point, une flèche ou un double-point pour faire référence aux membres d'une classe en C++?
J'ai créé la classe appelée Kwadrat et j'ai trois champs int à l'intérieur. Les blocs de code me donnent des conseils sur le fait que je peux entrer dans le champ de l'objet par ::
, .
et ->
. La flèche est celle qui ne marche que, mais pourquoi? Quelle est la différence entre ces trois?
#include <iostream>
using namespace std;
class Kwadrat{
public:
int val1, val2, val3;
Kwadrat(int val1, int val2, int val3)
{
this->val1 = val1;
//this.val2 = val2;
//this::val3 = val3;
}
};
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}
1.->
pour accéder aux variables et méthodes membres de l'objet via pointer
to object
Foo *foo = new Foo();
foo->member_var = 10;
foo->member_func();
2 ..
pour accéder aux variables et méthodes membres d’objet via l’objet instance
Foo foo;
foo.member_var = 10;
foo.member_func();
3 .::
pour accéder aux variables statiques et aux méthodes d’un class/struct
ou namespace
. Il peut également être utilisé pour accéder à des variables et à des fonctions depuis une autre portée (en réalité, classe, structure, espace de noms sont des étendues dans ce cas).
int some_val = Foo::static_var;
Foo::static_method();
int max_int = std::numeric_limits<int>::max();
En C++, vous pouvez accéder à des champs ou à des méthodes à l'aide d'opérateurs différents, en fonction du type:
Notez que :: doit être utilisé avec un nom de classe plutôt qu'une instance de classe, car les champs ou méthodes statiques sont communs à toutes les instances d'une classe.
class AClass{
public:
static int static_field;
int instance_field;
static void static_method();
void method();
};
alors vous accédez de cette façon:
AClass instance;
AClass *pointer = new AClass();
instance.instance_field; //access instance_field through a reference to AClass
instance.method();
pointer->instance_field; //access instance_field through a pointer to AClass
pointer->method();
AClass::static_field;
AClass::static_method();
En termes très simples, ::
Est l’opérateur de cadrage, .
Est l’opérateur d’accès (j’oublie le nom réel?) Et ->
Est la flèche de déréférence.
::
- Scopes une fonction. Autrement dit, le compilateur sait dans quelle classe la fonction vit et, ainsi, comment l'appeler. Si vous utilisez cet opérateur pour appeler une fonction, celle-ci est une fonction static
.
.
- Ceci permet l'accès à une fonction membre sur un objet déjà créé. Par exemple, Foo x; x.bar()
appelle la méthode bar()
sur l'objet instancié x
de type Foo
. Vous pouvez également l'utiliser pour accéder à des variables de classe publique.
->
- C'est essentiellement la même chose que .
, Sauf que cela fonctionne sur les types de pointeur. En substance, il déréférence le pointeur, que les appels .
. Utiliser ceci équivaut à (*ptr).method()
Les trois opérateurs ont des significations liées mais différentes, malgré la note trompeuse de l'IDE.
L'opérateur ::
Est appelé opérateur de résolution de portée, et il est utilisé pour passer d'un espace de noms ou d'une classe à l'un de ses membres.
Les opérateurs .
Et ->
Permettent d'accéder aux membres d'une instance d'objet et n'entrent en jeu qu'après la création d'une instance d'objet. Vous utilisez .
Si vous avez un objet réel (ou une référence à l'objet, déclaré avec &
Dans le type déclaré) et vous utilisez ->
Si vous avez un pointeur à un objet (déclaré avec *
dans le type déclaré).
L'objet this
est toujours un pointeur sur l'instance actuelle, raison pour laquelle l'opérateur ->
Est le seul qui fonctionne.
Exemples:
// In a header file
namespace Namespace {
class Class {
private:
int x;
public:
Class() : x(4) {}
void incrementX();
};
}
// In an implementation file
namespace Namespace {
void Class::incrementX() { // Using scope resolution to get to the class member when we aren't using an instance
++(this->x); // this is a pointer, so using ->. Equivalent to ++((*this).x)
}
}
// In a separate file lies your main method
int main() {
Namespace::Class myInstance; // instantiates an instance. Note the scope resolution
Namespace::Class *myPointer = new Namespace::Class;
myInstance.incrementX(); // Calling a function on an object instance.
myPointer->incrementX(); // Calling a function on an object pointer.
(*myPointer).incrementX(); // Calling a function on an object pointer by dereferencing first
return 0;
}
Vous avez un pointeur sur un objet. Par conséquent, vous devez accéder à un champ d'un objet pointé par le pointeur. Pour déréférencer le pointeur que vous utilisez *
, Et pour accéder à un champ, vous utilisez .
, Afin que vous puissiez utiliser:
cout << (*kwadrat).val1;
Notez que les parenthèses sont nécessaires. Cette opération est assez courante il y a longtemps (quand C était jeune), ils ont décidé de créer une méthode "abrégée" pour le faire:
cout << kwadrat->val1;
Ceux-ci sont définis pour être identiques. Comme vous pouvez le constater, le ->
Ne fait que combiner un *
Et un .
En une seule opération. Si vous traitiez directement avec un objet ou une référence à un objet, vous pouvez utiliser le .
Sans déréférencer un pointeur au préalable:
Kwadrat kwadrat2(2,3,4);
cout << kwadrat2.val1;
Le ::
Est l'opérateur de résolution de la portée. Il est utilisé lorsque vous devez uniquement qualifier le nom, mais vous ne traitez pas un objet individuel. Ce serait principalement pour accéder à un membre de données statique:
struct something {
static int x; // this only declares `something::x`. Often found in a header
};
int something::x; // this defines `something::x`. Usually in .cpp/.cc/.C file.
Dans ce cas, puisque x
est static
, il n'est associé à aucune instance particulière de something
. En fait, il existera même si aucune instance de ce type d'objet n'a été créée. Dans ce cas, nous pouvons y accéder avec l'opérateur de résolution de portée:
something::x = 10;
std::cout << something::x;
Notez cependant qu'il est également autorisé à accéder à un membre statique comme s'il était membre d'un objet particulier:
something s;
s.x = 1;
Du moins si la mémoire est utile, au début de l’histoire du C++, cela n’était pas autorisé, mais le sens est clair, ils ont donc décidé de l’autoriser.
Le '::' est pour les membres statiques.
-> est destiné aux pointeurs sur une instance de classe
. est pour les instances de classe
:: est pour les noms de classe - par exemple lors de l'utilisation d'un membre statique
D'autres ont répondu aux différentes syntaxes, mais notez bien que lorsque vous utilisez votre couts
, vous n'utilisez que ->
:
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}