El puntero this
[editar]Sintaxis
this | |||||||||
La palabra clave this
es una expresiónrvalue(hasta C++11)prvalue(desde C++11) cuyo valor es la dirección del parámetro de objeto implícito (objeto en el que se llama a la función miembro no estática). Puede aparecer en los siguientes contextos:
(hasta C++17) |
| (desde C++11) |
3) dentro del inicializador de miembro por defecto | (desde C++11) |
this
solo puede asociarse con la clase más interna donde aparece, incluso si la aparición no es válida en el contexto:
class Externa {int a[sizeof(*this)];// error: no dentro de una función miembrounsignedint sz = sizeof(*this);// correcto: en un inicializador de miembro por defectovoid f(){int b[sizeof(*this)];// correctostruct Interna {int c[sizeof(*this)];// error: no dentro de una función miembro de Interna// 'this' no está asociado a Externa// incluso si está dentro de una función miembro de Externa};}}
El tipo de this
en una función miembro de clase X
es X*
(puntero a X). Si la función miembro está declarada con una secuencia de calificadores-cvcv, el tipo de this
es cv X*
(puntero a X con idéntica calificación cv). Como los constructores y destructores no se pueden declarar con calificadores cv, el tipo de this
en ellos es siempre X*
, incluso cunado construyen o destruyen un objeto constante.
Cuando se usa un miembro de clase no estático en cualquier contexto donde se permita la palabra clave this
(cuerpos de funciones miembros no estáticas, listas de inicialización de miembro, inicializadores de miembro por defecto), se añade automáticamente un this->
implícito antes del nombre, resultado una expresión de acceso a miembro (que, si el miembro es una función miembro virtual, resulta es una llamada a función virtual).
En plantillas de clase, this
es una expresión dependiente, y se puede usar this->
explícito para obligar a otra expresión a volverse 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 se accede al valor del objeto o cualquiera de sus subobjetos a través de un glvalue que no se obtiene, directa o indirectamente, del puntero this
del constructor, el valor del objeto o subobjeto obtenido así no está especificado. Es decir, el puntero this no puede tener un alias en un constructor:
externstruct D d;struct D { D(int a): a(a), b(d.a){}// b(a) o b(this->a) sería correctoint a, b;}; D d = D(1);// debido a que b(d.a) no se obtuvo mediante this, d.b está sin especificar
Es posible ejecutar delete this;, si el programa puede garantizar que el objeto fue alojado mediante new, sin embargo, esto hace que todos los punteros al objeto desasignado no sean válidos, incluido el puntero this
en sí mismo: después de delete this;, dicha función miembro no puede hacer referencia a un miembro de una clase (ya que esto implica una desreferencia implícita de this
) y no se puede llamar a ninguna otra función miembro.
Esto se usa, por ejemplo, en la función miembro del bloque de control de std::shared_ptr responsable de disminuir el contador de referencias, cuando la última referencia al objeto administrado queda fuera del ámbito. | (desde C++11) |
class ref {// ...void incRef(){++mnRef;}void decRef(){if(--mnRef ==0) delete this;}};
[editar]Ejemplo
class T {int x; void foo(){ x =6;// igual a 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 desambiguación} int y; T(int x): x(x), // usa el parámetro x para iniciar el miembro x y(this->x)// usa el miembro x para iniciar el miembro y{} T& operator=(const T& b){ x = b.x;return*this;// muchos operadores sobrecargados devuelven *this}};
[editar]Informe de defectos
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
---|---|---|---|
CWG 760 | C++98 | cuando this se usa en una clase anidada,no estaba especificado si está asociado con la clase anidada o con la que la envuelve | this siempre se asocia con la clase anidada másinterna, independientemente de si está en una función miembro no estática |