Срок службы временных объектов, используемых во время перегруженного оператора доступа к цепочкам->C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Срок службы временных объектов, используемых во время перегруженного оператора доступа к цепочкам->

Сообщение Anonymous »

В соответствии с тем, что я знаю, значение результата перегруженного оператора-> () может быть любым типом t при условии, что t является либо типом указателя, либо это класс /struct, который также раскрывает перегруженного оператора-> () . По сути, компилятор должен потенциально объединить несколько вызовов этих перегруженных операторов доступа к членам, пока не будет получено результат значения типа указателя. Что меня интересует, так это то, гарантирует ли стандарт что -либо, как именно это «цепочка» должна выглядеть с синтаксической точки зрения. Рассмотрим следующий пример: < /p>

Код: Выделить всё

struct A {
int data;
A* operator->() { return this; }
};

struct B {
A operator->() { return A(); }
};

struct C {
B operator->() { return B(); }
};

int main() {
C()->data = 1;
}
Часть особого интереса здесь-перегруженная a* a :: operator-> () , которая возвращает указатель на себя (

Код: Выделить всё

return this
). Мой первый вопрос заключается в том, является ли это на самом деле законным делать с точки зрения языка. Я полагаю, что это так, поскольку он соответствует требованию перегруженного оператора-> () возврата типа указателя. Единственная проблема, которую я вижу здесь, заключается в том, что могут быть некоторые условия, при которых возвращенная a* указатель может стать свисающим. И в этом заключается второй вопрос - может ли процесс цепочки множественного оператора -> () вместе компилятором за кулисами привести к недействительным. Это может произойти, например, если выражение c ()-> data = 1; будет «развертываться» в следующую синтаксически аналогичную конструкцию:

Код: Выделить всё

A* _internal_compiler_var = ((C().operator->()).operator->()).operator->(); // temporary A is constructed and immediately destroyed after obtaining the pointer value
_internal_compiler_var->data = 1; // Oops : dangling A* pointer
Напротив, выражение c ()-> data = 1; будет действительным при условии, что компилятор «развертывает». p>

Код: Выделить всё

(((C().operator->()).operator->()).operator->())->data = 1; // OK : destruction of temporary A instance is performed after the assignment
< /code>
Итак, чтобы подвести итог, что я хотел бы знать 2 вещи: < /p>
[list]
[*] () 
Возвращение этого указателя действителен, и если это так, если есть какие -либо потенциальные проблемы, которые могут возникнуть из -за этого
[*] неявные/явные гарантии о (временном) объекте Время жизни используется в цепочке перегруженного оператора-> () (частично, если эти временные объекты разрушаются после выражения в окружении или уничтожаются где-то в середине, в то время как полученное значение указателя оценивается)
[/list]

Подробнее здесь: https://stackoverflow.com/questions/794 ... cess-opera
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»