Por lo general, no this->es necesario , está implícito.
A veces, existe una ambigüedad de nombre, donde se puede usar para eliminar la ambigüedad de los miembros de la clase y las variables locales. Sin embargo, aquí hay un caso completamente diferente donde this->se requiere explícitamente.
Considere el siguiente código:
template<class T>struct A {int i;};template<class T>struct B : A<T>{int foo(){returnthis->i;}};int main(){
B<int> b;
b.foo();}
Si omite this->, el compilador no sabe cómo tratar i, ya que puede existir o no en todas las instancias de A. Para decirle que iefectivamente es miembro de A<T>, para cualquiera T, this->se requiere el prefijo.
Nota: aún es posible omitir el this->prefijo usando:
template<class T>struct B : A<T>{using A<T>::i;// explicitly refer to a variable in the base classint foo(){return i;// i is now known to exist}};
Este es un caso particularmente desagradable. Me ha mordido antes.
Jason Baker
5
Esta puede ser una pregunta tonta, pero no entiendo por qué ipodría no existir en A. ¿Podría darme un ejemplo?
Cam Jackson
1
@CamJackson Probé el código en Visual Studio. los resultados son los mismos sin importar "esto->" existiera o no. ¿Alguna idea?
Peng Zhang
8
@CamJackson: Se pueden especializar clases en el tipo:template<> struct A<float> { float x; };
Macke
31
Si declara una variable local en un método con el mismo nombre que un miembro existente, tendrá que usar this-> var para acceder al miembro de la clase en lugar de a la variable local.
#include<iostream>usingnamespace std;class A
{public:int a;void f(){
a =4;int a =5;
cout << a << endl;
cout <<this->a << endl;}};int main(){
A a;
a.f();}
En el último caso, la nota que usted no puede llamar a un constfunción de miembro de manera temporal ( Type(rhs).swap(*this);es legal y correcto), pero una lata temporal se une a un parámetro de referencia no constante (rechazos del compilador swap(Type(rhs));, así como this->swap(Type(rhs));)
Ben Voigt
5
Hay pocos casos en los thisque se debe usar el uso, y hay otros en los que se debe usar elthis puntero es una forma de resolver un problema.
1) Alternativas disponibles : para resolver la ambigüedad entre las variables locales y los miembros de la clase, como lo ilustra @ASk .
2) Sin alternativa: para devolver un puntero o una referencia thisdesde una función miembro. Esto se hace con frecuencia (y se debe hacer) cuando se sobrecarga operator+, operator-, operator=, etc:
Hacer esto permite un modismo conocido como " encadenamiento de métodos ", donde se realizan varias operaciones en un objeto en una línea de código. Como:
Algunos consideran esta consistencia, otros la consideran una abominación. Cuente conmigo en el último grupo.
3) Sin alternativa: Para resolver nombres en tipos dependientes. Esto surge cuando se utilizan plantillas, como en este ejemplo:
#include<iostream>template<typenameVal>classValHolder{private:Val mVal;public:ValHolder(constVal& val):
mVal (val){}Val&GetVal(){return mVal;}};template<typenameVal>classValProcessor:publicValHolder<Val>{public:ValProcessor(constVal& val):ValHolder<Val>(val){}ValComputeValue(){// int ret = 2 * GetVal(); // ERROR: No member 'GetVal'int ret =4*this->GetVal();// OK -- this tells compiler to examine dependant type (ValHolder)return ret;}};int main(){ValProcessor<int> proc (42);constint val = proc.ComputeValue();
std::cout << val <<"\n";}
4) Alternativas disponibles: como parte del estilo de codificación, para documentar qué variables son variables miembro en lugar de variables locales. Prefiero un esquema de nomenclatura diferente donde los miembros varibales nunca pueden tener el mismo nombre que los locales. Actualmente estoy usando mNamepara miembros y namepara locales.
Solo tiene que usar this-> si tiene un símbolo con el mismo nombre en dos espacios de nombres potenciales. Toma por ejemplo:
class A {public:void setMyVar(int);void doStuff();private:int myVar;}void A::setMyVar(int myVar){this->myVar = myVar;// <- Interesting point in the code}void A::doStuff(){int myVar =::calculateSomething();this->myVar = myVar;// <- Interesting point in the code}
En los puntos interesantes del código, la referencia a myVar se referirá a la myVar local (parámetro o variable). Para acceder al miembro de la clase también llamado myVar, necesita usar explícitamente "this->".
Este es el único uso this->que es trivial de evitar (simplemente dé a la variable local un nombre diferente). Todos los usos realmente interesantes de thisni siquiera se mencionan en esta respuesta.
cmaster - reinstalar a monica
4
Los otros usos para esto (como pensé cuando leí el resumen y la mitad de la pregunta ...), sin tener en cuenta (mal) la desambiguación de nombres en otras respuestas, son si desea lanzar el objeto actual, vincularlo en un objeto de función o utilícelo con un puntero a miembro.
Casts
voidFoo::bar(){
misc_nonconst_stuff();constFoo* const_this =this;
const_this->bar();// calls const versiondynamic_cast<Bar*>(this)->bar();// calls specific virtual function in case of multi-inheritance}voidFoo::bar()const{}
No, no lo necesitas , puedes usarlo . También puede usar un nombre diferente para el argumento de la función, que tiene la ventaja de no tener dos entidades con el mismo nombre.
cmaster - reinstalar a monica
3
El principal (o puedo decir, el único) propósito del thispuntero es que apunte al objeto utilizado para invocar una función miembro.
Con base en este propósito, podemos tener algunos casos en los que solo el uso del thispuntero puede resolver el problema.
Por ejemplo, tenemos que devolver el objeto de invocación en una función miembro con argumento es un mismo objeto de clase:
class human {...
human & human::compare(human & h){if(condition)return h;// argument objectelsereturn*this;// invoking object}};
O puede convertirlo en lengthmutable, o incluso ponerlo en una estructura anidada. Dejar de lado la consistencia casi nunca es una buena idea.
Richard J. Ross III
3
Por favor no lo hagas. Si el miembro se va a cambiar de constfunciones de miembro, debería serlo mutable. De lo contrario, está complicando la vida para usted y otros mantenedores.
research.att.com/~bs/
es ahorastroustrup.com
. Nuevo enlace: stroustrup.com/bs_faq2.html#thisRespuestas:
Por lo general, no
this->
es necesario , está implícito.A veces, existe una ambigüedad de nombre, donde se puede usar para eliminar la ambigüedad de los miembros de la clase y las variables locales. Sin embargo, aquí hay un caso completamente diferente donde
this->
se requiere explícitamente.Considere el siguiente código:
Si omite
this->
, el compilador no sabe cómo tratari
, ya que puede existir o no en todas las instancias deA
. Para decirle quei
efectivamente es miembro deA<T>
, para cualquieraT
,this->
se requiere el prefijo.Nota: aún es posible omitir el
this->
prefijo usando:fuente
i
podría no existir enA
. ¿Podría darme un ejemplo?template<> struct A<float> { float x; };
Si declara una variable local en un método con el mismo nombre que un miembro existente, tendrá que usar this-> var para acceder al miembro de la clase en lugar de a la variable local.
huellas dactilares:
5
4
fuente
Hay varias razones por las que podría necesitar usar
this
puntero de forma explícita.fuente
Aunque generalmente no me gusta en particular, he visto a otros usar esto-> ¡simplemente para obtener ayuda de intellisense!
fuente
Algunos estándares de codificación utilizan el enfoque (2), ya que afirman que hace que el código sea más fácil de leer.
Ejemplo:
suponga que MyClass tiene una variable miembro llamada 'recuento'
fuente
Otro caso es cuando se invocan operadores. Por ejemplo, en lugar de
puedes decir
Cuál podría ser más legible. Otro ejemplo es el de copiar e intercambiar:
No sé por qué no está escrito,
swap(temp)
pero esto parece ser común.fuente
const
función de miembro de manera temporal (Type(rhs).swap(*this);
es legal y correcto), pero una lata temporal se une a un parámetro de referencia no constante (rechazos del compiladorswap(Type(rhs));
, así comothis->swap(Type(rhs));
)Hay pocos casos en los
this
que se debe usar el uso, y hay otros en los que se debe usar elthis
puntero es una forma de resolver un problema.1) Alternativas disponibles : para resolver la ambigüedad entre las variables locales y los miembros de la clase, como lo ilustra @ASk .
2) Sin alternativa: para devolver un puntero o una referencia
this
desde una función miembro. Esto se hace con frecuencia (y se debe hacer) cuando se sobrecargaoperator+
,operator-
,operator=
, etc:Hacer esto permite un modismo conocido como " encadenamiento de métodos ", donde se realizan varias operaciones en un objeto en una línea de código. Como:
Algunos consideran esta consistencia, otros la consideran una abominación. Cuente conmigo en el último grupo.
3) Sin alternativa: Para resolver nombres en tipos dependientes. Esto surge cuando se utilizan plantillas, como en este ejemplo:
4) Alternativas disponibles: como parte del estilo de codificación, para documentar qué variables son variables miembro en lugar de variables locales. Prefiero un esquema de nomenclatura diferente donde los miembros varibales nunca pueden tener el mismo nombre que los locales. Actualmente estoy usando
mName
para miembros yname
para locales.fuente
Solo tiene que usar this-> si tiene un símbolo con el mismo nombre en dos espacios de nombres potenciales. Toma por ejemplo:
En los puntos interesantes del código, la referencia a myVar se referirá a la myVar local (parámetro o variable). Para acceder al miembro de la clase también llamado myVar, necesita usar explícitamente "this->".
fuente
this->
que es trivial de evitar (simplemente dé a la variable local un nombre diferente). Todos los usos realmente interesantes dethis
ni siquiera se mencionan en esta respuesta.Los otros usos para esto (como pensé cuando leí el resumen y la mitad de la pregunta ...), sin tener en cuenta (mal) la desambiguación de nombres en otras respuestas, son si desea lanzar el objeto actual, vincularlo en un objeto de función o utilícelo con un puntero a miembro.
Casts
Unión
ptr-to-member
Espero que ayude a mostrar otros usos de esto además de este-> miembro.
fuente
Necesita usar
this
para eliminar la ambigüedad entre parámetros / variables locales y variables miembro.fuente
El principal (o puedo decir, el único) propósito del
this
puntero es que apunte al objeto utilizado para invocar una función miembro.Con base en este propósito, podemos tener algunos casos en los que solo el uso del
this
puntero puede resolver el problema.Por ejemplo, tenemos que devolver el objeto de invocación en una función miembro con argumento es un mismo objeto de clase:
fuente
Encontré otro caso interesante de uso explícito del puntero "this" en el libro Effective C ++.
Por ejemplo, digamos que tiene una función constante como
No desea calcular la longitud de String para cada llamada, por lo tanto, desea almacenarlo en caché haciendo algo como
Pero esto no se compilará, está cambiando el objeto en una función constante.
El truco para resolver esto requiere fundición esta a un no-const esto :
Entonces, podrás hacer arriba
fuente
length
mutable, o incluso ponerlo en una estructura anidada. Dejar de lado la consistencia casi nunca es una buena idea.const
funciones de miembro, debería serlomutable
. De lo contrario, está complicando la vida para usted y otros mantenedores.