The
this
pointer
Contenidos |
Sintaxis
this
|
|||||||||
La expresión this es una prvalue expresión cuyo valor es la dirección del parámetro de objeto implícito (objeto sobre el cual se está llamando a la función miembro de objeto implícito). Puede aparecer en los siguientes contextos:
|
3)
Dentro de
inicializador por defecto de miembro
.
4)
Dentro de
lista de captura
de una expresión lambda.
|
(desde C++11) |
Explicación
this solo puede asociarse con la clase envolvente más interna de su aparición, incluso si la aparición es inválida en el contexto:
class Outer { int a[sizeof(*this)]; // Error: no está dentro de una función miembro unsigned int sz = sizeof(*this); // OK: en inicializador de miembro por defecto void f() { int b[sizeof(*this)]; // OK struct Inner { int c[sizeof(*this)]; // Error: no está dentro de una función miembro de Inner // “this” no está asociado con Outer // incluso si está dentro de una función miembro de Outer }; } };
El tipo de
this
en una función miembro de la clase
X
es
X*
(puntero a X). Si la función miembro está
declarada con una secuencia de calificadores cv
cv
, el tipo de
this
es
cv
X*
(puntero a X idénticamente calificado con cv). Dado que los constructores y destructores no pueden declararse con calificadores cv, el tipo de
this
en ellos es siempre
X*
, incluso al construir o destruir un objeto const.
En las plantillas de clase, this es una expresión dependiente , y el uso explícito de this - > puede utilizarse para forzar que otra expresión se convierta en dependiente.
template<typename T> struct B { int var; }; template<typename T> struct D : B<T> { D() { // var = 1; // Error: “var” no fue declarado en este ámbito this->var = 1; // Correcto } };
Durante la construcción de un objeto, si el valor del objeto o cualquiera de sus subobjetos es accedido a través de un glvalue que no se obtiene, directa o indirectamente, del puntero this del constructor, el valor del objeto o subobjeto así obtenido es no especificado. En otras palabras, el puntero this no puede ser aliaseado en un constructor:
extern struct D d; struct D { D(int a) : a(a), b(d.a) {} // b(a) o b(this->a) sería correcto int a, b; }; D d = D(1); // porque b(d.a) no obtuvo a a través de this, d.b ahora no está especificado
Es posible ejecutar
delete this
;
, si el programa puede garantizar que el objeto fue asignado mediante
new
, sin embargo, esto invalida cada puntero al objeto desasignado, incluyendo el propio puntero
this
: después de que
delete this
;
retorne, dicha función miembro no puede referirse a un miembro de la clase (ya que esto implica una desreferencia implícita de
this
) y ninguna otra función miembro puede ser llamada.
Esto puede utilizarse en la función miembro del puntero con conteo de referencias (por ejemplo, std::shared_ptr ) (since C++11) responsable de decrementar el conteo de referencias, cuando la última referencia al objeto gestionado sale del ámbito.
class ref { // ... void incRef() { ++mnRef; } void decRef() { if (--mnRef == 0) delete this; } };
Palabras clave
Ejemplo
class T { int x; void foo() { x = 6; // igual que this->x = 6; this->x = 5; // uso explícito de this-> } void foo() const { // x = 7; // Error: *this es constante } void foo(int x) // el parámetro x oculta al miembro con el mismo nombre { this->x = x; // x sin calificar se refiere al parámetro // se requiere "this->" para desambiguar } int y; T(int x) : x(x), // usa el parámetro x para inicializar el miembro x y(this->x) // usa el miembro x para inicializar el miembro y {} T& operator=(const T& b) { x = b.x; return *this; // muchos operadores sobrecargados devuelven *this } };
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Se aplica a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 760 | C++98 |
cuando se usa
this
en una clase anidada, no se especificaba
si estaba asociado con la clase anidada o con la clase contenedora |
this
siempre se asocia con
la clase anidada más interna, independientemente de si está en una función miembro no estática |
| CWG 2271 | C++98 |
this
podría ser aliaseado al
construir un objeto no constante |
también se prohíbe el alias
en este caso |
| CWG 2869 | C++98 |
no estaba claro si
this
podía usarse en una
función miembro estática de una clase no asociada |
se aclaró |