Когда я должен явно писать this->member в методе
класс?
Когда я должен явно использовать указатель `this`?
Ответ 1
Обычно вам не нужно, this-> подразумевается.
Иногда возникает неоднозначность имени, где его можно использовать для устранения неоднозначности членов класса и локальных переменных. Однако здесь совершенно другой случай, когда this-> явно требуется.
Рассмотрим следующий код:
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();
}
Если вы опустите this->, компилятор не знает, как лечить i, поскольку он может существовать или не существовать во всех экземплярах A. Чтобы сказать, что i действительно является членом A<T>, для любого T требуется префикс this->.
Примечание. Можно опустить префикс this-> с помощью:
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
    }
};
		Ответ 2
Если вы объявляете локальную переменную в методе с тем же именем, что и существующий член, вам придется использовать this- > var для доступа к члену класса вместо локальной переменной.
#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();
}
печатает:
5 
4
Ответ 3
Существует несколько причин, по которым вам может понадобиться явно использовать указатель this.
- Если вы хотите передать ссылку на свой объект на какую-то функцию.
 - Когда есть локально объявленный объект с тем же именем, что и объект-член.
 - Когда вы пытаетесь получить доступ к элементам зависимых базовых классов .
 - Некоторые люди предпочитают обозначать визуально устранять неоднозначность доступа членов в своем коде.
 
Ответ 4
- Если переменная-член будет скрыта локальная переменная
 - Если вы просто хотите чтобы было ясно ясно, что вы вызывают метод/переменную экземпляра
 
 
Некоторые стандарты кодирования используют подход (2), поскольку они утверждают, что он упрощает чтение кода.
Пример:
 Предположим, что MyClass имеет переменную-член, называемую "count" 
void MyClass::DoSomeStuff(void)
{
   int count = 0;
   .....
   count++;
   this->count = count;
}
		Ответ 5
Другим случаем является вызов операторов. Например. вместо
bool Type::operator!=(const Type& rhs)
{
    return !operator==(rhs);
}
вы можете сказать
bool Type::operator!=(const Type& rhs)
{
    return !(*this == rhs);
}
Что может быть более читаемым. Другим примером является копирование и своп:
Type& Type::operator=(const Type& rhs)
{
    Type temp(rhs);
    temp.swap(*this);
}
Я не знаю, почему это не написано swap(temp), но это кажется общим.
Ответ 6
Хотя я обычно не особенно люблю это, я видел, как другие используют это- > просто для получения помощи от intellisense!
Ответ 7
Существует несколько случаев использования this, и есть другие, где использование указателя this является одним из способов решения проблемы.
1) Доступны альтернативы. Чтобы устранить двусмысленность между локальными переменными и членами класса, как показано @ASk.
2)  Нет альтернативы: Чтобы вернуть указатель или ссылку на this из функции-члена. Это часто делается (и должно быть сделано) при перегрузке operator+, operator-, operator= и т.д.:
class Foo
{
  Foo& operator=(const Foo& rhs)
  {
    return * this;
  }
};
Выполнение этого разрешает идиому, известную как " цепочка методов", где вы выполняете несколько операций над объектом в одной строке кода. Например:
Student st;
st.SetAge (21).SetGender (male).SetClass ("C++ 101");
Некоторые считают это consise, другие считают это мерзостью. Подсчитайте меня в последней группе.
3) Нет альтернативы:. Чтобы разрешить имена в зависимых типах. Это происходит при использовании шаблонов, как в этом примере:
#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)  Доступные альтернативы. В качестве части стиля кодирования для документирования переменных используются переменные-члены, а не локальные переменные. Я предпочитаю другую схему именования, в которой члены varibales никогда не могут иметь то же имя, что и локальные. В настоящее время я использую mName для членов и name для локальных пользователей.
Ответ 8
Вам нужно использовать this для устранения неоднозначности между параметрами/локальными переменными и переменными-членами.
class Foo
{
protected:
  int myX;
public:
  Foo(int myX)
  {
    this->myX = myX; 
  }
};
		Ответ 9
Вам нужно использовать это → если у вас есть символ с тем же именем в двух потенциальных пространствах имен. Возьмем, к примеру:
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
}
В интересных моментах кода, ссылаясь на myVar, будет ссылаться на локальный (параметр или переменная) myVar. Чтобы получить доступ к члену класса, также называемому myVar, вам нужно явно использовать "this → ".
Ответ 10
Другой использует для этого (как я думал, когда я читал сводку и половину вопроса...), игнорируя (плохое) именование неоднозначности в других ответах, - это если вы хотите использовать текущий объект, привяжите его в объект функции или использовать его с указателем на элемент.
Слепки
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 {}
Привязка
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-к-член
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)();
    }
}
Надеемся, что это поможет показать другое использование этого, а не только этого → участника.
Ответ 11
Некоторые люди говорили о том, как this должна быть ссылкой, и я не мог согласиться больше. Я просто хотел бы сказать, что уродливая линия прекомпилятора может имитировать это:
#define self (*this)
Не используйте это: -)
Ответ 12
Я нашел еще один интересный случай явного использования указателя "this" в книге Effective С++.
Например, скажем, что у вас есть функция const, например
  unsigned String::length() const
Вы не хотите вычислять длину строки для каждого вызова, поэтому вы хотите кэшировать ее, делая что-то вроде
  unsigned String::length() const
  {
    if(!lengthInitialized)
    {
      length = strlen(data);
      lengthInitialized = 1;
    }
  }
Но это не будет компилироваться - вы меняете объект в функции const.
Трюк для решения этого требует отнести это к неконстантному:
  String* const nonConstThis = (String* const) this;
Затем вы сможете сделать это выше
  nonConstThis->lengthInitialized = 1;
		Ответ 13
Основной (или я могу сказать, единственная) цель указателя this заключается в том, что он указывает на объект, используемый для вызова функции-члена.
Основы для этой цели, мы можем иметь некоторые случаи, которые могут решить только с помощью указателя this.
Например, мы должны вернуть вызывающий объект в функции-члене с аргументом - это один и тот же объект класса:
class human {
... 
human & human::compare(human & h){
    if (condition)
        return h;       // argument object
    else 
        return *this;   // invoking object
    }
};