Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
898
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
951
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
941
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1726
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4398
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Когда вы используете ключевое слово "this"?
Мне было любопытно, как другие люди используют это ключевое слово. Я обычно использую его в конструкторах, но я также могу использовать его по всему классу в других методах. Примеры:
В конструкторе:
public Light(Vector v)
{
this.dir = new Vector(v);
}
В другом месте
public void SomeMethod()
{
Vector vec = new Vector();
double d = (vec * vec) - (this.radius * this.radius);
}
Я не хочу, чтобы это прозвучало язвительно, но это не имеет значения.
Серьезно.
Посмотрите на вещи, которые важны: ваш проект, ваш код, ваша работа, ваша личная жизнь. Ни один из них не будет иметь своего успеха rest от того, используете ли вы ключевое слово "this" для квалификации доступа к полям. Это ключевое слово не поможет вам отправить вовремя. Это не уменьшит количество ошибок, не окажет заметного влияния на качество кода или его ремонтопригодность. Это не даст вам прибавку к зарплате или позволит проводить меньше времени в офисе.
На самом деле это просто вопрос стиля. Если вам нравится "this", то используйте его. Если вам это нужно, чтобы получить правильную семантику, то используйте его. Правда в том, что каждый программист имеет свой собственный уникальный стиль программирования. Этот стиль отражает представления конкретного программиста о том, как должен выглядеть "most aesthetically pleasing code". По определению, любой другой программист, который читает ваш код, будет иметь другой стиль программирования. Это означает, что всегда будет что-то, что вы сделали, что другой парень не любит или сделал бы по-другому. В какой-то момент какой-то парень прочитает ваш код и будет ворчать о чем-то.
Я бы не переживал из-за этого. Я просто хотел бы убедиться, что код настолько эстетичен, насколько это возможно в соответствии с вашими собственными вкусами. Если вы спросите 10 программистов, как форматировать код, вы получите около 15 различных мнений. Лучше сосредоточиться на том, как код учитывается. Правильно ли все абстрагировано? Разве я выбирал для вещей осмысленные названия? Есть ли много дублирования кода? Есть ли способы, которыми я могу все упростить? Я думаю, что правильное решение этих вопросов окажет самое большое положительное влияние на ваш проект, ваш код, вашу работу и вашу жизнь. По совпадению, это, вероятно, также заставит другого парня ворчать меньше всего. Если ваш код работает, легко читается и хорошо учитывается, другой парень не будет тщательно изучать, как вы инициализируете поля. Он просто будет использовать ваш код, восхищаться его величием, а затем перейдет к чему-то другому.
Существует несколько вариантов использования этого ключевого слова в C#.
- Чтобы квалифицировать участников, скрытых под похожим именем
- Чтобы объект передавал себя в качестве параметра другим методам
- Чтобы объект возвращал себя из метода
- Для объявления индексаторов
- Для объявления методов расширения
- Передача параметров между конструкторами
- Чтобы внутренне переназначить значение типа значения (struct).
- Чтобы вызвать метод расширения на текущем экземпляре
- Чтобы привести себя к другому типу
- Для цепных конструкторов, определенных в том же классе
Вы можете избежать первого использования, не имея членовых и локальных переменных с одинаковыми именами в области видимости, например, следуя общим соглашениям об именовании и используя свойства (Pascal case) вместо полей (camel case), чтобы избежать столкновения с локальными переменными (также camel case). В C# 3.0 поля могут быть легко преобразованы в свойства с помощью автоматически реализуемых свойств .
Я использую его только тогда, когда это абсолютно необходимо, т. е. когда другая переменная затеняет другую. Такие как здесь:
class Vector3
{
float x;
float y;
float z;
public Vector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
Или, как указывает Райан Фокс, Когда вам нужно передать это в качестве параметра. (Локальные переменные имеют приоритет над переменными-членами)
Лично я стараюсь всегда использовать это при обращении к переменным-членам. Это помогает уточнить код и сделать его более читаемым. Даже если нет никакой двусмысленности, кто-то, читающий мой код в первый раз, не знает этого, но если он видит, что это используется последовательно, он будет знать, смотрит ли он на переменную-член или нет.
Я не могу поверить, что все люди, которые говорят, что использование его всегда является "best practice" и так далее.
Используйте "this", когда есть неопределенность, как в Примере кори , или когда вам нужно передать объект в качестве параметра, как в Примере Райана . Нет никакой причины использовать его иначе, потому что возможность разрешить переменную на основе цепочки областей должна быть достаточно ясной, чтобы квалифицирующие переменные с ней не были нужны.
EDIT: документация C# по "this" указывает на еще одно использование, помимо двух упомянутых мною, ключевого слова "this" - для объявления индексаторов
EDIT: @Juan: Да, я не вижу никакой несогласованности в своих заявлениях - есть 3 случая, когда я использовал бы ключевое слово "this" (как описано в документации C#), и это время, когда вам действительно это нужно . Вставлять "this" перед переменными в конструкторе, когда нет никакого затенения, - это просто пустая трата клавиш и моего времени при чтении, это не дает никакой пользы.
Еще одно несколько редкое использование этого ключевого слова - когда вам нужно вызвать явную реализацию интерфейса из класса реализации. Вот надуманный пример:
class Example : ICloneable
{
private void CallClone()
{
object clone = ((ICloneable)this).Clone();
}
object ICloneable.Clone()
{
throw new NotImplementedException();
}
}
Вот когда я его использую:
- Доступ к частным методам из класса (для дифференциации)
- Передача текущего объекта другому методу (или в качестве объекта-отправителя, в случае события)
- При создании методов расширения: D
Я не использую это для частных полей, потому что я префиксую имена переменных частных полей с подчеркиванием (_).
[C++]
Я согласен с бригадой "use it when you have to". Излишне украшать код этим не очень хорошая идея, потому что компилятор не предупредит вас, когда вы забудете это сделать. Это создает потенциальную путаницу для людей, ожидающих, что это всегда будет там, т. е. им придется думать об этом.
Итак, когда бы вы его использовали? Я только что осмотрел какой-то случайный код и нашел эти примеры (я не выношу суждения о том, являются ли эти вещи хорошими или нет):
- Передача функции "yourself".
- Присвоение "yourself" указателю или что-то в этом роде.
- Отливки, т. е. вверх/вниз отливок (безопасный или иначе), отбросить константность и др.
- Компилятор ввел двусмысленность.
Я использую его, когда в функции, которая принимает ссылку на объект того же типа, Я хочу, чтобы было совершенно ясно , на какой объект я ссылаюсь и где.
Например
class AABB
{
// ... members
bool intersects( AABB other )
{
return other.left() < this->right() &&
this->left() < other.right() &&
// +y increases going down
other.top() < this->bottom() &&
this->top() < other.bottom() ;
}
} ;
(против)
class AABB
{
bool intersects( AABB other )
{
return other.left() < right() &&
left() < other.right() &&
// +y increases going down
other.top() < bottom() &&
top() < other.bottom() ;
}
} ;
На первый взгляд, к какому AABB относится right() ? this добавляет немного осветлителя.
В ответе Якуба Штурца его #5 о передаче данных между контрукторами, вероятно, можно было бы немного пояснить. Это происходит в перегруженных конструкторах и является единственным случаем, когда использование this является обязательным. В следующем примере мы можем вызвать параметризованный конструктор из конструктора без параметров с параметром по умолчанию.
class MyClass {
private int _x
public MyClass() : this(5) {}
public MyClass(int v) { _x = v;}
}
Я обнаружил, что это особенно полезная функция в некоторых случаях.
Вы всегда должны использовать его, я использую его для дифференциации частных полей и параметров (потому что наши соглашения об именовании гласят, что мы не используем префиксы для имен членов и параметров (и они основаны на информации, найденной в интернете, поэтому я считаю, что это лучшая практика))
- вот это.'помогает найти членов в классе 'this' с большим количеством членов (обычно из-за глубокой цепочки наследования).
Нажатие CTRL+пробел не помогает в этом, потому что оно также включает типы; where-as 'this.- включая членов ONLY.
Я обычно удаляю его, как только у меня есть то, что мне было нужно: но это просто мой стиль прорыва.
С точки зрения стиля, Если вы одинокий рейнджер - вы решаете; если вы работаете на компанию, придерживайтесь политики компании (посмотрите на материал в системе управления версиями и посмотрите, что делают другие люди). С точки зрения использования его для квалификации членов, ни то, ни другое не является правильным или неправильным. Единственное неправильное - это непоследовательность , это золотое правило стиля. Оставь этих придурков подбирать другим. Вместо этого потратьте свое время на обдумывание реальных проблем кодирования-и, очевидно, кодирования-вместо этого.
[C++]
это используется в операторе присваивания, где большую часть времени вы должны проверять и предотвращать странные (непреднамеренные, опасные или просто пустые траты времени для программы) вещи, такие как:
A a;
a = a;
Ваш оператор назначения будет записан:
A& A::operator=(const A& a) {
if (this == &a) return *this;
// we know both sides of the = operator are different, do something...
return *this;
}
this на компиляторе C++
this на компиляторе C++
Компилятор C++ будет автоматически искать символ, если он не найдет его немедленно. Иногда, в большинстве случаев, это хорошо:
- использование метода материнского класса, если вы не перегружали его в дочернем классе.
- продвижение значения типа в другой тип
Но иногда вы просто не хотите, чтобы компилятор догадался. Вы хотите, чтобы компилятор подобрал правильный символ, а не другой.
Для меня это время, когда внутри метода я хочу получить доступ к методу-члену или переменной-члену. Я просто не хочу, чтобы какой-то случайный символ был выбран только потому, что я написал printf вместо print . this->printf не стал бы компилироваться.
Дело в том, что с C устаревшими библиотеками ( § ), устаревшим кодом, написанным много лет назад ( § § ), или тем, что может произойти в языке, где копирование/вставка является устаревшей, но все еще активной функцией, иногда, говоря компилятору, чтобы он не играл в Остроумие, это отличная идея.
Вот почему я использую this .
( § ) это все еще остается для меня загадкой, но теперь я задаюсь вопросом, является ли тот факт, что вы включаете заголовок <windows.h> в свой источник, причиной того, что все унаследованные символы библиотек C будут загрязнять ваше глобальное пространство имен
( § § ) осознание того, что "вам нужно включить заголовок, но что включение этого заголовка нарушит ваш код, потому что он использует какой-то тупой макрос с общим именем", является одним из тех моментов русской рулетки в жизни кодера
Существует одно использование, которое еще не было упомянуто в C++, и это не относится к собственному объекту или не вызывает неоднозначности члена из полученной переменной.
Вы можете использовать this для преобразования несамостоятельного имени в имя, зависящее от аргумента, внутри классов шаблонов, наследуемых от других шаблонов.
template <typename T>
struct base {
void f() {}
};
template <typename T>
struct derived : public base<T>
{
void test() {
//f(); // [1] error
base<T>::f(); // quite verbose if there is more than one argument, but valid
this->f(); // f is now an argument dependent symbol
}
}
Шаблоны компилируются с помощью двухпроходного механизма. Во время первого прохода разрешаются и проверяются только не зависящие от аргумента имена, в то время как зависимые имена проверяются только на когерентность, без фактической замены аргументов шаблона.
На этом этапе компилятор практически не имеет информации о том, что такое base<T> (обратите внимание, что специализация базового шаблона может превратить его в совершенно разные типы, даже неопределенные типы), поэтому он просто предполагает, что это тип. На этом этапе несамостоятельный вызов f , который кажется просто естественным для программиста, является символом, который компилятор должен найти как член derived или в замкнутых пространствах имен-чего не происходит в Примере - и он будет жаловаться.
Решение заключается в превращении несамостоятельного имени f в зависимое имя. Это можно сделать несколькими способами, явно указав тип, в котором он реализован ( base<T>::f -- добавление base<T> делает символ зависимым от T , и компилятор просто предположит, что он будет существовать, и отложит фактическую проверку для второго прохода, после замены аргумента.
Второй способ, гораздо более сортирующий, если вы наследуете от шаблонов, которые имеют более одного аргумента или длинных имен, - это просто добавление this-> перед символом. Поскольку класс шаблона, который вы реализуете, зависит от аргумента (он наследуется от base<T>), this-> зависит от аргумента, и мы получаем тот же результат: this->f проверяется во втором раунде, после замены параметров шаблона.