2012-03-07 2 views
5

Является ли указатель this указателем? Думаю, вам это нужно, если бы вы функционально проходили по экземпляру класса, на который указывает this. Но с точки зрения установки/получения/вызова/любых членов, this всегда факультативно?Когда требуется «это»?

Я отметил этот C++, потому что это тот язык, о котором мне особенно интересно, но если кто-то может подтвердить, что конструкция такая же для Java и других языков OO, которые используют указатель this, это было бы оценено.

ответ

8

Вам это нужно, если у вас есть локальная переменная с тем же именем, что и переменная-член. В этом случае локальная переменная называется теневой переменной-членом. Чтобы перейти к переменной-члену в этой ситуации, вы должны использовать this.

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

+0

Для C++ последнего рассмотрения верно, но для Java или C#, это не всегда условности – Geoffroy

+0

Вот почему вы всегда называете свой член переменные, отличные от ваших локальных, например 'm_myVar' или' myVar_' и так далее. Поскольку использование 'this' не применяется, большинство проектов предпочитают принудительно использовать стандарт именования для переменных-членов. –

+1

Я бы не сказал, что это хорошая форма использования 'this' все время. Используйте его, только если есть тени. Обычно тени тоже можно избежать. –

11

Там три случая я могу думать:

Если вы хотите просто передать указатель на текущий класс:

class B; 
struct A { 
    B* parent_; 
    A(B* parent) : parent_(parent) {} 
}; 

struct B { 
    A* a; 
    B() : a(new A(this)) {} 
}; 

В конструктора или члена функции, где член является затененный аргументом:

struct A { 
    int a; 
    void set_a(int a) { this->a = a; } 
}; 

Здесь переменная-член «a» затенена аргументом «a», поэтому this-> используется для доступа к элементу вместо аргумента.

(вышеприведенный пример отредактированный быть функцией, а не конструктор, так как вы обычно не может присвоить этот путь в конструкторе)


Если доступ/защищенную переменную-член или функции в базовом классе класса шаблона

template <class T> 
struct A { 
    int a; 
}; 

template <class T> 
struct B : public A<T> { 
    int f() { return this->a; } 
} 

здесь, a в одиночку не будет зависимым именем, поэтому компилятор ожидает найти декларацию о нем в B или базу B, не DEP конец на T. Добавление this-> делает поиск зависимым от типа this, а поскольку this является зависимым, поиск a отложен до тех пор, пока не будет создан экземпляр f().

Можно было бы написать return A::a вместо return this->a, но в присутствии нескольких баз, прямых или косвенных, с использованием this-> является более гибким. Этот альтернативный синтаксис также ограничен переменными-членами и не виртуальными функциями - если он используется с виртуальной функцией, он будет вызываться непосредственно, а не выполнять вызов виртуальной функции.

+0

Вы всегда можете использовать имя класса :: variablename для доступа к нему, так как это может быть использовано для него, но это необязательно. – PlasmaHH

+0

@PlasmaHH Да, я интерпретировал вопрос как «в каких ситуациях пишут» это «не избыточно», а не «в какой ситуации пишут» это «единственный способ добиться чего-то» – je4d

+1

На самом деле только ваш первый пример правильный , для двух других использование 'this' является необязательным. В вашем втором примере использование списка инициализаторов ctor является идиоматическим C++ и не будет иметь проблемы двусмысленности, например. 'A :: A (int a): a (a) {}' действителен и не является двусмысленным (по крайней мере, для компилятора). –

-1

иногда требуется «это», возможно, когда вы передаете свой объект другой функции. взгляда на этих C# код (для открытия модальной формы с этим родителем)

Form1 f = new Form(); 
f.ShowDialog(this); 
+0

Это не похоже на C++. – svick

Смежные вопросы