Почему «это» указатель, а не ссылка?

183

Я читал ответы на этот вопрос плюсы и минусы C ++ и получил это сомнение, читая комментарии.

Программисты часто путают, что «это» - указатель, а не ссылка. Другая путаница заключается в том, что «hello» не относится к типу std :: string, а вычисляется как char const * (указатель) (после преобразования массива в указатель) - Йоханнес Шауб - litb 22 декабря 2008 г. в 1:56

Это только показывает, что он не использует те же соглашения, что и другие (более поздние) языки. - Le Dorfier 22 декабря 2008 в 3:35

Я бы назвал эту вещь довольно тривиальной проблемой. И, к сожалению, спасибо за обнаружение нескольких ошибок в моих примерах неопределенного поведения. :) Хотя я не понимаю, какое отношение имеет размер к первому. Указателю просто не разрешено указывать вне выделенной памяти - jalf 22 декабря 2008 в 4:18

Это постоянный указатель? - Yesraaj 22 декабря 2008 в 6:35

это может быть константой, если метод const int getFoo () const; <- в области действия getFoo «this» является константой и поэтому доступно только для чтения. Это предотвращает ошибки и обеспечивает некоторый уровень гарантии для вызывающей стороны, что объект не изменится. - Дуг Т. 22 декабря 2008 в 16:42

Вы не можете переназначить «это». то есть вы не можете делать «this = & other;», потому что это значение. но это типа T *, а не типа T const. т.е. это непостоянный указатель. если вы используете метод const, то это указатель на const. T const. но сам указатель неконстантен - Йоханнес Шауб - litb 22 декабря 2008 в 17:53

Думайте об «этом» следующим образом: #define this (this_ + 0), где компилятор создает «this_» как указатель на объект и делает «this» ключевым словом. Вы не можете назначить «это», потому что (this_ + 0) является значением. конечно, это не так (такого макроса нет), но это может помочь понять это - Йоханнес Шауб - litb 22 декабря 2008 г. в 17:55

Мой вопрос: почему thisуказатель не является ссылкой? Есть ли какая-то конкретная причина сделать его указателем?


Некоторые дополнительные аргументы, почему thisиметь ссылку, имеет смысл:

  • Рассмотрим Item 1из More Effective C++ : используйте ссылки, когда гарантируется, что у нас есть действительный объект, т.е. не NULL (моя интерпретация).
  • Кроме того, ссылки считаются более безопасными, чем указатели (потому что мы не можем испортить память с помощью случайного указателя).
  • В-третьих, синтаксис для доступа к reference ( .) немного лучше и короче, чем доступ к указателям ( ->или (*)).
Нэвин
источник
5
@paulm Чего бы на самом деле достиг этот хак? Не thisвсегда оценивать true?
iFreilicht
6
@ paulm Я не думаю, что это действительно C ++. Вызов методов на nullptr для объекта приводит к неопределенному поведению.
antred
5
@paulm Может быть, это работает в некоторых случаях, но представьте, если метод был вирулентным. Как можно выполнить поиск v-таблицы без объекта?
Джейсон Крейтон
3
@paulm Если вы видели это в рабочем коде, оставьте корабль! Это UB.
Алиса
6
Я просто оставлю это здесь ... (из affwin2.inl из MFC):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Кристофер Оиклз

Ответы:

176

Когда язык только начинал развиваться, в ранних выпусках с реальными пользователями не было никаких ссылок, только указатели. Ссылки были добавлены, когда была добавлена ​​перегрузка операторов, так как она требует, чтобы ссылки работали согласованно.

Одним из применений thisявляется то, что объект получает указатель на себя. Если бы это была ссылка, мы должны были бы написать &this. С другой стороны, когда мы пишем оператор присваивания, мы должны return *thisэто выглядеть проще return this. Так что, если бы у вас был чистый лист, вы могли бы спорить в любом случае. Но C ++ развивался постепенно в ответ на отзывы сообщества пользователей (как и большинство успешных вещей). Значение обратной совместимости полностью подавляет незначительные преимущества / недостатки, возникающие из-за thisтого, что они являются ссылкой или указателем.

Дэниел Уорвикер
источник
4
Ну, это также часто полезно для объекта, чтобы получить ссылку на себя. Я бы сказал, что это более распространенное использование. Как бы то ни было, основная причина, как вы сказали, не существовала, когда создавался указатель this.
Джалф
20
И, если бы это была ссылка, было бы трудно перегрузить operator &что-нибудь полезное. Должен быть какой-то особый синтаксис для получения адреса, который не будет проходить operator &.
Всезнающий
10
@conio - вы можете проверить, что в следующий раз вы будете рядом с компилятором C ++! :) Что-то вроде:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Даниэль Эрвикер
14
@ Omnifarious вы могли бы написать, &reinterpret_cast<char&>(this);чтобы получить реальный адрес для перегрузки operator&(на самом деле, это то, что boost::addressofделает).
Йоханнес Шауб -
9
Поскольку в действительности нет никакого смысла thisбыть нулевым, мне кажется, что ссылка действительно более подходящая.
Ponkadoodle
114

Немного опоздал на вечеринку ... Прямо из уст лошади вот что говорит Бьярн Страуструп (что по сути повторяется или взято из книги "Дизайн и эволюция C ++"):

Почему " this" не является ссылкой?

Потому что «это» было введено в C ++ (на самом деле в C с классами), прежде чем ссылки были добавлены. Кроме того, я выбрал " this", чтобы следовать использованию Simula, а не (позже) Smalltalk-использованию "self".

Майкл Берр
источник
2
Да, self было бы неплохо для согласованности с другими языками, да ладно.
Pilkch