Есть ли разница между использованием указателя "this" и его не использовать?

Использует ли указатель "this" указатель на другую программу во время выполнения?

Просто чтобы привести пример, чтобы лучше объяснить вопрос:

class C
{
public:
    void set_x(int val){ x = val; }
    void set_this_x(int val){ this->x = val; }

private:
    int x;
};

Выполняет ли функция "C:: set_x()" во время выполнения 1 операция меньше, чем "C:: set_this_x()"?

Спасибо!: -)

Ответ 1

Нет никакой разницы между двумя функциями-членами. Это должно быть, поскольку это то, что должен сказать стандарт С++ (ISO/IEC 14882: 2003):

9.3.1 Нестатические функции-члены [class.mfct.nonstatic]

2. Когда id-expression (5.1), который не является частью члена класса синтаксиса доступа (5.2.5) и не используется для формирования указателя на элемент (5.3.1) используется в теле нестатической функции-члена класса X или используется в mem-initializer для конструктора класса X, если имя lookup (3.4.1) разрешает имя в id-expression для нестатического nontype члена класса X или базового класса X, id-expression преобразуется в выражение доступа к члену класса (5.2.5) с использованием (*this) (9.3.2) в качестве постфиксного выражения влево оператора .. Имя члена затем ссылается на члена объект, для которого вызывается функция.

5.2.5 Доступ к члену класса [expr.ref]

3. Если E1 имеет тип "указатель на класс X", то выражение E1->E2 преобразуется в эквивалентную форму (*(E1)).E2;...

Таким образом, это означает следующий код:

class C
{
public:
    void set_x(int val) { x = val; }
    void set_this_x(int val) { this->x = val; }
private:
    int x;
};

был бы преобразован в следующий код в соответствии с 9.3.1/2 и 5.2.5/3:

class C
{
public:
    void set_x(int val)      { (*this).x = val; }   // as per 9.3.1/2
    void set_this_x(int val) { (*(this)).x = val; } // as per 5.2.5/3
private:
    int x;
};

Чтобы показать, что действительно нет никакой разницы, по крайней мере для одного компилятора, здесь боковое сравнение разборки функций C::set_x() и C::set_this_x(), которые компилятор VС++ испускает с отключенными оптимизациями (/Od):

  void set_x(int val){ x = val; }      void set_this_x(int val){ this->x = val; }
push      ebp                        push      ebp
mov       ebp,esp                    mov       ebp,esp
sub       esp,0CCh                   sub       esp,0CCh
push      ebx                        push      ebx
push      esi                        push      esi
push      edi                        push      edi
push      ecx                        push      ecx
lea       edi,[ebp-0CCh]             lea       edi,[ebp-0CCh]
mov       ecx,33h                    mov       ecx,33h
mov       eax,0CCCCCCCCh             mov       eax,0CCCCCCCCh
rep stos  dword ptr es:[edi]         rep stos  dword ptr es:[edi]
pop       ecx                        pop       ecx
mov       dword ptr [ebp-8],ecx      mov       dword ptr [ebp-8],ecx
mov       eax,dword ptr [this]       mov       eax,dword ptr [this]
mov       ecx,dword ptr [val]        mov       ecx,dword ptr [val]
mov       dword ptr [eax],ecx        mov       dword ptr [eax],ecx
pop       edi                        pop       edi
pop       esi                        pop       esi
pop       ebx                        pop       ebx
mov       esp,ebp                    mov       esp,ebp
pop       ebp                        pop       ebp
ret       4                          ret       4

Обратите внимание, что компилятор создает ту же самую сборку для обеих функций-членов.

Ответ 2

Нет, это не делает разницу во времени выполнения, это просто синтаксис. Указатель this по-прежнему доступен в первой функции, он явно указывается неявно, а не явно.

Кстати, это пахнет как преждевременная оптимизация - сначала напишите чистый код, а быстрый код позже.

Ответ 3

Синтаксис this->member требуется, если вы наследуете шаблон шаблона:

template<typename T>
class Base
{
protected:
    T x;
};

template<typename T>
class Derived : Base<T>
{
public:
    void whatever()
    {
        T a = x;         // error
        T b = this->x;   // ok
    }
};

Ответ 4

Нет, нет разницы.
когда вы ссылаетесь на элемент напрямую, компилятор действительно пересматривает его через this.

Ответ 5

То же самое. Тем не менее, "this" может использоваться для устранения неоднозначности в определенных случаях.

class C
{
public:
    void set_x(int x){ x = x; } // does nothing
    void set_this_x(int x){ this->x = x; } // sets the variable

private:
    int x;
};

Ответ 6

Нет.

Если вы наткнулись на это выражение в чей-то код, оно, вероятно, возникло примерно так:

struct A
{
    int x;

    void set_X(int x)
    {
        this->x = x;
    }
};

Ответ 7

Никакой разницы, компилятор уже автоматически генерирует код для этого- > Пока это лишний синтаксис, есть две веские причины для его использования:

  • с помощью редактора, который поддерживает автозаполнение. Когда вы набираете "this- > ", редактор выдает окно инструмента, в котором представлен список членов класса на выбор. Это может ускорить типизацию и помогает избежать глупых ошибок компиляции из-за ввода ошибок.

  • это помогает избежать необходимости создавать имена искусственных аргументов. Вы можете дать аргументу то же имя, что и член класса: void set_x (int x) {this- > x = x; }.

Ответ 8

Что вы можете сказать foo вместо this->foo - это просто синтаксический сахар. Нет никакой разницы в скомпилированном коде. Как и весь синтаксический сахар, небольшая горстка порицает его, но больше всего его любит. Чтобы узнать, где вы столкнулись с проблемой, попробуйте использовать язык, подобный perl или python, который не предоставляет этот синтаксический сахар. Код Python переполнен self.foo; в коде perl OO вы увидите self->foo повсюду. Это может быть немного отвлекающим.

Ответ 9

В один из периодов времени это имеет значение, когда вы указываете локальную переменную с тем же именем, что и член класса. Например:

class Example {

public:

    int something();
    int somethingElse();

}


int Example::somethingElse() {
    int something = something(); // ERROR
    int something = this->something(); // OK
    // ...
}