punteros operaciones declaracion con cadenas aritmetica apuntadores c++ this

operaciones - punteros c++ pdf



¿Cuándo debería hacer un uso explícito del puntero `this`? (13)

¿Cuándo debería escribir explícitamente este this->member en un método de una clase?


  1. Donde una variable miembro estaría oculta por una variable local
  2. Si solo quiere dejar en claro explícitamente que está llamando a un método de instancia / variable


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:
Suponer que MyClass tiene una variable miembro llamada ''conteo''

void MyClass::DoSomeStuff(void) { int count = 0; ..... count++; this->count = count; }


Algunas personas estaban hablando de cómo this debería ser una referencia y no podría estar más de acuerdo. Solo me gustaría decir que una línea fea de código de preprocesador puede simular eso:

#define self (*this)

No uses esto :-)


Aunque normalmente no me gusta en particular, he visto a otros usar esto-> ¡simplemente para obtener ayuda de intellisense!


Debe usar this para eliminar la ambigüedad entre un parámetro / variables locales y variables miembro.

class Foo { protected: int myX; public: Foo(int myX) { this->myX = myX; } };


El principal (o puedo decir, el único) propósito de this puntero es que apunta al objeto utilizado para invocar una función de miembro.

Basándonos en este propósito, podemos tener algunos casos en los que solo usar this puntero puede resolver el problema.

Por ejemplo, tenemos que devolver el objeto que invoca 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 object else return *this; // invoking object } };


Encontré otro caso interesante de uso explícito del puntero "this" en el libro Effective C ++.

Por ejemplo, supongamos que tienes una función const como

unsigned String::length() const

No desea calcular la longitud de String para cada llamada, por lo tanto, desea almacenarla en caché haciendo algo así como

unsigned String::length() const { if(!lengthInitialized) { length = strlen(data); lengthInitialized = 1; } }

Pero esto no se compilará; está cambiando el objeto en una función const.

El truco para resolver esto requiere lanzar esto a una no-const esto :

String* const nonConstThis = (String* const) this;

Entonces, podrás hacerlo en la parte superior

nonConstThis->lengthInitialized = 1;


Hay pocos casos en los que se deba utilizar esto, y hay otros en los que usar this 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 se ilustra en @ASk .

2) Sin alternativa: devolver un puntero o referencia a this desde una función de miembro. Esto se realiza con frecuencia (y se debe hacer) cuando se sobrecarga el operator+ , operator- , operator= , etc.

class Foo { Foo& operator=(const Foo& rhs) { return * this; } };

Hacer esto permite un modismo conocido como " encadenamiento de métodos ", donde realiza varias operaciones en un objeto en una línea de código. Como:

Student st; st.SetAge (21).SetGender (male).SetClass ("C++ 101");

Algunos consideran este concepto, otros lo consideran una abominación. Cuentame en el último grupo.

3) Sin alternativa: para resolver nombres en tipos dependientes. Esto aparece cuando se usan plantillas, como en este ejemplo:

#include <iostream> template <typename Val> class ValHolder { private: Val mVal; public: ValHolder (const Val& val) : mVal (val) { } Val& GetVal() { return mVal; } }; template <typename Val> class ValProcessor : public ValHolder <Val> { public: ValProcessor (const Val& val) : ValHolder <Val> (val) { } Val ComputeValue() { // 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); const int 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 comparación con variables locales. Prefiero un esquema de nombres diferente donde los miembros varibales nunca pueden tener el mismo nombre que los locales. Actualmente estoy usando mName para miembros y name para locales.


Hay varias razones por las que podría necesitar usar this puntero de forma explícita.

  • Cuando desee pasar una referencia a su objeto a alguna función.
  • Cuando hay un objeto declarado localmente con el mismo nombre que el objeto miembro.
  • Cuando intenta acceder a miembros de clases base dependientes .
  • Algunas personas prefieren la notación para desambiguar visualmente los accesos de los miembros en su código.

Los otros usos para esto (como pensé cuando leí el resumen y la mitad de la pregunta ...), sin tener en cuenta (desagradables) la denominación de desambiguación en otras respuestas, si quieres lanzar el objeto actual, vincularlo en un objeto de función o usarlo con un puntero a miembro.

Moldes

void Foo::bar() { misc_nonconst_stuff(); const Foo* const_this = this; const_this->bar(); // calls const version dynamic_cast<Bar*>(this)->bar(); // calls specific virtual function in case of multi-inheritance } void Foo::bar() const {}

Unión

void Foo::baz() { for_each(m_stuff.begin(), m_stuff.end(), bind(&Foo:framboozle, this, _1)); for_each(m_stuff.begin(), m_stuff.end(), [this](StuffUnit& s) { framboozle(s); }); } void Foo::framboozle(StuffUnit& su) {} std::vector<StuffUnit> m_stuff;

ptr-to-member

void Foo::boz() { bez(&Foo::bar); bez(&Foo::baz); } void Foo::bez(void (Foo::*func_ptr)()) { for (int i=0; i<3; ++i) { (this->*func_ptr)(); } }

Espero que ayude mostrar otros usos de esto que simplemente este-> miembro.


Otro caso es cuando se invoca a los operadores. Por ejemplo, en lugar de

bool Type::operator!=(const Type& rhs) { return !operator==(rhs); }

puedes decir

bool Type::operator!=(const Type& rhs) { return !(*this == rhs); }

Que podría ser más legible. Otro ejemplo es el copy-and-swap:

Type& Type::operator=(const Type& rhs) { Type temp(rhs); temp.swap(*this); }

No sé por qué no está escrito swap(temp) pero esto parece ser común.


Por lo general, no es necesario, this-> está implícito.

A veces, hay una ambigüedad de nombre, donde se puede utilizar 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-> es explícitamente requerido.

Considera el siguiente código:

template<class T> struct A { int i; }; template<class T> struct B : A<T> { int foo() { return this->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 decir que soy un miembro de A<T> , para cualquier T , se requiere el prefijo this-> .

Nota: es posible omitir este this-> usando:

template<class T> struct B : A<T> { using A<T>::i; // explicitly refer to a variable in the base class int foo() { return i; // i is now known to exist } };


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 la variable local.

#include <iostream> using namespace 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(); }

huellas dactilares:

5
4


Solo tiene que usar esto-> si tiene un símbolo con el mismo nombre en dos posibles espacios de nombres. 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, al referirse a myVar se referirá al local (parámetro o variable) myVar. Para acceder al miembro de la clase también llamado myVar, debe usar explícitamente "this->".