Является ли значение указателя `this` постоянным в течение всего времени существования объекта?

19

thisГарантируется ли значение указателя постоянным в течение жизни определенного объекта? Я не могу представить себе случай, когда это изменится, но не знаю, не пропустил ли я что-то.

Даниэль Лангр
источник
4
Значение thisуказателя всегда является значением адреса объекта, для которого была вызвана функция. Таким образом, вопрос эквивалентен «может ли объект изменить адрес своей памяти в течение жизни?»
Аконкагуа
2
Стоит отметить: если неформально говорить о продолжительности жизни, объект, по которому перемещаются std::move, изменит thisуказатели. Формально мы бы сказали, что это два разных объекта, но неофициально можно думать о них как о «одинаковых», что может породить путаницу, если не обращать внимания.
Корт Аммон

Ответы:

27

thisГарантируется ли значение указателя постоянным в течение жизни определенного объекта?

Да .

Как говорит пользователь Aconcagua : значение thisуказателя всегда является значением адреса объекта, для которого функция была вызвана 1 . Таким образом, вопрос эквивалентен с:

Может ли объект изменить адрес своей памяти в течение жизни?

Это невозможно по определению lifetime2 . Время жизни объекта начинается, когда или после его хранения получено и заканчивается до того, когда он выпущен.


1) [class.this]/1

В теле функции- [class.mfct]члена non-static ( ) ключевое слово thisявляется prvalue , значением которого является указатель на объект, для которого вызывается функция.

2) [basic.life]/1 (акцент мой)

Время жизни объекта или ссылки является свойством среды выполнения объекта или ссылки. Говорят, что переменная имеет пустую инициализацию, если она инициализирована по умолчанию, и, если она имеет тип класса или (возможно, многомерный) массив, этот тип класса имеет тривиальный конструктор по умолчанию. Время жизни объекта типа Tначинается, когда :

  • хранения с правильным выравниванием и размером для типа Tполучаются , и
  • его инициализация (если есть) завершена (включая пустую инициализацию) ( [dcl.init]), за исключением того, что если объект является членом объединения или его подобъектом, его время жизни начинается только в том случае, если этот член объединения является инициализированным членом в объединении ( [dcl.init.aggr], [class.base.init]) или как описано в [class.union].

Время жизни объекта oтипа Tзаканчивается, когда :

  • если Tтип не является классом, объект уничтожается, или
  • Если Tэто тип класса, начинается вызов деструктора, или
  • хранилище, которое занимает объект, освобождается или используется объектом, который не вложен в o( [intro.object]).
МКЦ
источник
Означает ли это, что было бы невозможно (незаконно) для достаточно сложной среды выполнения реализовать автоматическое сжатие памяти для программы на C ++? Или это просто означает, что он должен вести себя «как если бы», чтобы обеспечивать одинаковое значение thisкаждый раз, независимо от движений в куче?
Александр - Восстановить Монику
2
@ Ясно, что правило «как будто» преобладает. Всегда.
YSC
1
@ Alexander-ReinstateMonica vtable - похожая концепция, которая снижает производительность, но она принята, так как преимущества перевешивают недостатки. Современные процессоры действительно эффективны при косвенном обращении.
Марк Рэнсом
1
@MarkRansom " - это указатель, который гарантированно является адресом объекта, или компилятор может добавить уровень косвенности? " По определению , ptr - это адрес объекта, но "адрес" может быть абстрактным понятием высокого уровня. , Но затем, если вы вводите косвенное обращение, вам нужна атомарность, вам нужна блокировка, вам нужна куча дополнительной работы для всех обращений к любому объекту, если есть потоки. Просто по внешнему виду я чувствую, что это неработоспособно (и я даже не учел тот факт, что C / C ++ удваивается как язык низкого уровня).
любопытный парень
1
@curiousguy вы делаете хорошие замечания, и я больше не утверждаю, что косвенное обращение будет практичным. Это все еще делает хороший мысленный эксперимент все же.
Марк Рэнсом
8

У объекта есть область хранения. thisуказывает там.

[intro.object]/1

Объект занимает область хранения в период его строительства ( [class.cdtor]), на протяжении всей его жизни и в период разрушения ( [class.cdtor]).

Caleth
источник
-1

Значение thisгарантированно будет постоянным, если программа когда-либо его считывает, если впоследствии некоторые биты значения чтения невозможно собрать мусором или если впоследствии некоторые биты значения чтения вышли за пределы программы. Во всех остальных случаях он ведет себя как кот Шредингера, то есть он постоянен и изменчив одновременно.

atomsymbol
источник
Извините, совсем не понимаю. Что такое сборка мусора и выход за пределы программы ?
Даниэль Лангр
@DanielLangr Биты значения идентификатораthis
atomymbol
Это не отвечает на мой вопрос. Что такое мусор для сбора некоторых битов? Или избежать их вне программы?
Даниэль Лангр
@DanielLangr Трудно объяснить небольшим фрагментом текста
atomymbol