Namespaces
Variants

The this pointer

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Table des matières

Syntaxe

this

L'expression this est une prvalue expression dont la valeur est l'adresse du implicit object parameter (objet sur lequel la fonction membre implicite est appelée). Elle peut apparaître dans les contextes suivants :

2) Dans la déclaration de toute fonction membre d'objet implicite, n'importe où après la séquence (optionnelle) de qualificatifs cv, incluant la spécification d'exception et le type de retour trailing (depuis C++11) .
4) Dans la liste de capture d'une expression lambda.
(depuis C++11)

Explication

this ne peut s'associer qu'avec la classe englobante la plus interne de son apparition, même si l'apparition est invalide dans le contexte :

class Outer
{
    int a[sizeof(*this)];            // Erreur : pas dans une fonction membre
    unsigned int sz = sizeof(*this); // OK : dans l'initialiseur de membre par défaut
    void f()
    {
        int b[sizeof(*this)];     // OK
        struct Inner
        {
            int c[sizeof(*this)]; // Erreur : pas dans une fonction membre de Inner
                                  // « this » n'est pas associé à Outer
                                  // même s'il se trouve dans une fonction membre de Outer
        };
    }
};

Le type de this dans une fonction membre de la classe X est X* (pointeur vers X). Si la fonction membre est déclarée avec une séquence de qualificatifs cv cv , le type de this est cv X* (pointeur vers X identiquement qualifié cv). Comme les constructeurs et destructeurs ne peuvent pas être déclarés avec des qualificatifs cv, le type de this dans ceux-ci est toujours X* , même lors de la construction ou destruction d'un objet const.

Dans les modèles de classe, this est une expression dépendante , et l'utilisation explicite de this - > peut être utilisée pour forcer une autre expression à devenir dépendante.

template<typename T>
struct B
{
    int var;
};
template<typename T>
struct D : B<T>
{
    D()
    {
        // var = 1;    // Erreur : « var » n'a pas été déclaré dans cette portée
        this->var = 1; // OK
    }
};

Pendant la construction d'un objet, si la valeur de l'objet ou de l'un de ses sous-objets est accédée via une glvalue qui n'est pas obtenue, directement ou indirectement, à partir du pointeur this du constructeur, la valeur de l'objet ou du sous-objet ainsi obtenue est non spécifiée. En d'autres termes, le pointeur this ne peut pas être aliasé dans un constructeur :

extern struct D d;
struct D
{
    D(int a) : a(a), b(d.a) {} // b(a) ou b(this->a) serait correct
    int a, b;
};
D d = D(1); // parce que b(d.a) n'a pas obtenu a via this, d.b est maintenant non spécifié

Il est possible d'exécuter delete this ; , si le programme peut garantir que l'objet a été alloué par new , cependant, cela rend invalide tout pointeur vers l'objet désalloué, y compris le pointeur this lui-même : après le retour de delete this ; , une telle fonction membre ne peut pas se référer à un membre de classe (puisque cela implique un déréférencement implicite de this ) et aucune autre fonction membre ne peut être appelée.

Cela peut être utilisé dans la fonction membre du pointeur à comptage de références (par exemple, std::shared_ptr ) (depuis C++11) responsable de la décrémentation du compteur de références, lorsque la dernière référence à l'objet géré sort de la portée.

class ref
{
    // ...
    void incRef() { ++mnRef; }
    void decRef() { if (--mnRef == 0) delete this; }
};

Mots-clés

this

Exemple

class T
{
    int x;
    void foo()
    {
        x = 6;       // identique à this->x = 6;
        this->x = 5; // utilisation explicite de this->
    }
    void foo() const
    {
    //  x = 7; // Erreur : *this est constant
    }
    void foo(int x) // le paramètre x masque le membre du même nom
    {
        this->x = x; // x non qualifié fait référence au paramètre
                     // "this->" est requis pour lever l'ambiguïté
    }
    int y;
    T(int x) : x(x),      // utilise le paramètre x pour initialiser le membre x
               y(this->x) // utilise le membre x pour initialiser le membre y
    {}
    T& operator=(const T& b)
    {
        x = b.x;
        return *this; // de nombreux opérateurs surchargés retournent *this
    }
};

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Applicable à Comportement publié Comportement corrigé
CWG 760 C++98 lorsque this est utilisé dans une classe imbriquée, il était
non spécifié s'il était associé à
la classe imbriquée ou à la classe englobante
this s'associe toujours avec
la classe imbriquée la plus interne,
indépendamment du fait qu'il se trouve dans
une fonction membre non statique
CWG 2271 C++98 this pouvait être aliasé lors de la
construction d'un objet non constant
l'alias est également
interdit dans ce cas
CWG 2869 C++98 il n'était pas clair si this pouvait être utilisé dans une
fonction membre statique d'une classe non associée
clarifié