ELEPHANT technologies, l’ESN locale et à taille humaine spécialisée sur 2 métiers : le développement et le pilotage autour de 4 expertises : hardware, embarqué, software et web.

 

Aujourd’hui c’est Léna notre ingénieur en #software qui nous explique en détail dans cet article, le rôle de l’opérateur en C++, le prototype de la surcharge ainsi que quelques exemples

 

Let’s go !



 

Surcharger l'opérateur -> en C++

 

 

  • Qu’est-ce que l’opérateur ->?

L’opérateur ->, de son petit nom opérateur membre de pointeur, est un des opérateurs d’accès membres. De base, il permet d’accéder à un attribut ou à une méthode d’un objet via un pointeur.

 

Exemple :

1

2

3

std::string str = "Hello, World !";

std::string* ptr = &str;

bool is_empty = ptr->empty();

Il est l’équivalent de la combinaison de l’opérateur de déréférencement “*” et de l’opérateur membre d’objet “.” , par exemple le snippet de code précédent est l’équivalent de celui-ci :

1

2

3

4

std::string str = "Hello, World !";

std::string* ptr = &str;

// On utilise des parenthèses à cause de la précédence de l'opérateur . sur l'opérateur *

bool is_empty = (*ptr).empty();

 


 

La surcharge, ça se passe comment ?

 

  • Le prototype de la surcharge

Pour surcharger l’opérateur ->, il faut déclarer une méthode nommée operator->, sans argument, qui retourne soit :

➜ Un pointeur

➜ Un objet, par référence ou par valeur, qui a lui-même une surcharge de l’opérateur ->

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

Exemple où l'on retourne un pointeur

struct StrWrapper

{

    std::string* operator->()

    {

        return &str;

    }

    

    std::string str;

};

 

// Exemple où l'on retourne un objet qui a un opérateur -> surchargé

struct WrapperOfWrapper

{   

    StrWrapper operator->()

    {

        return str_wrapper;

    }

    

    StrWrapper str_wrapper;

};


 

 

  • Le comportement si un pointeur est retourné

 

C’est le cas le plus simple : dans ce cas, on utilise directement le pointeur retourné comme un pointeur classique, et ainsi on peut accéder à un attribut ou à une méthode comme on le ferait avec un pointeur normal. Si on reprend la classe StrWrapper de l’exemple ci-dessus, on peut écrire ce code-là :

 

1

2

3

4

5

StrWrapper str_wrapper{"Awesome"};

std::cout << str_wrapper->size() << std::endl; // Affiche 7

// La ligne ci-dessus et l'équivalent de la ligne ci-dessous car l'opérateur ->

// retourne un pointeur vers la std::string contenu dans la classe

std::cout << str_wrapper.str.size() << std::endl; // Affiche 7 aussi

 

 

  • Le comportement si un objet est retourné

 

Dans ce cas, le compilateur va appeler l’opérateur -> de l’objet retourné : si ce nouvel appel retourne un objet, on recommence successivement jusqu’à obtenir un pointeur, ce qui nous fait retomber sur le premier cas expliqué précédemment. Voici un exemple reprenant les classes StrWrapper et WrapperOfWrapper pour mieux comprendre :
 

1

2

3

4

5

6

WrapperOfWrapper wow{"Awesome"};

std::cout << wow->size() << std::endl; // Affiche 7

// C'est l'équivalent de ça :

std::cout << wow.str_wrapper->size() << std::endl;

// Qui est lui même l'équivalent de ça :

std::cout << wow.str_wrapper.str.size() << std::endl; 


 

  • Pourquoi surcharger cet opérateur ?

 

On peut citer deux raisons communes de surcharger l’opérateur -> :

➜ Avoir une utilisation et un comportement similaire à celui d’un pointeur : c’est le cas par exemple pour les pointeurs intelligents

➜ Pouvoir accéder facilement aux méthodes et attributs d’une classe wrappée à partir d’une autre classe (qui la contient). On peut citer les itérateurs de la bibliothèque standard comme exemple.


 

En conclusion,

Nous vous proposons quelques exemples de surcharges de l’opérateur -> dans la bibliothèque standard

 

 

Si ce sujet vous intéresse, n’hésitez pas à aller regarder l’article sur le langage C ++ ainsi que ses paramètres.

 


🐘 Un grand merci à Lena Bertho pour la rédaction de cet article !

 


 

Sources :