web-dev-qa-db-fra.com

Quelle est la différence entre "::" "." et "->" en c ++

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;
}
74
Yoda

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();
152
Andrew

En C++, vous pouvez accéder à des champs ou à des méthodes à l'aide d'opérateurs différents, en fonction du type:

  • ClassName :: FieldName: champ et méthodes publics statiques de la classe
  • ClassInstance.FieldName: accéder à un champ public (ou à une méthode) par le biais d'une référence de classe
  • ClassPointer-> FieldName: accès à un champ public (ou à une méthode) déréférencant un pointeur de classe

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();
25
Heisenbug

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

16
RageD

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;
}
8
Platinum Azure

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.

8
Jerry Coffin

Le '::' est pour les membres statiques.

2
Marcin Zaluski

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

2
Gir

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;
}
1
psynnott