Идиоматично ли противостоять "этому"?
При создании проклятой версии Snake я обнаружил, что указатель this
связать для реконструкции из метода update.
Проблема в том, что, хотя это очень удобно (избавляет от необходимости привязывать "игрока" к игровому объекту), оно не выглядит особенно идиоматичным.
Используя змею в качестве примера, мы уничтожим ее и реконструируем, когда мы находимся внутри вызова метода начальной (?) Змеи.
Вот пример повторного связывания this
в некоторой структуре A
:
struct A
{
int first;
A(int first) : first(first){};
void method(int i);
};
void A::method(int i)
{
*this = i;
}
Ответы
Ответ 1
Это законно, но если бы я увидел это, я бы спросил, знал ли автор, что они делают: они действительно this->operator=()
вызвать this->operator=()
? Конечно, есть лучший способ сделать... что бы они ни пытались сделать.
В вашем случае *this = i
эквивалентно this->operator=(i)
. Так как там не определен operator=(int)
, он использует оператор присваивания по умолчанию и конструктор A(int)
для выполнения this->operator=(A(i))
. Чистый эффект такой же, как если бы вы написали:
this->first = i;
Почему они просто не присвоили first
напрямую? Я бы спросил.
Если по какой-то причине вам нужны все эти шаги, я бы по крайней мере сделал неявную конструкцию A(int)
явной:
*this = A(i);
Ответ 2
*this = i;
неявно создает новый экземпляр A
как A::A(int)
не является explicit
конструктором и поэтому создает неявное преобразование из int
в A
*this = i;
затем вызывает по умолчанию A::operator=
с этим новым экземпляром A
созданным из i
. Затем новый экземпляр A
уничтожается.
Так что код *this = i;
эквивалентно operator=(A(i));
в твоем случае.
Это допустимо, но читаемость кода страдает от такого большого количества неявных действий.
Ответ 3
Вы не уничтожаете объект, на который указывает this
, вы называете его operator=
, который first
скопирует временный объект, инициализированный из i
. Вы уничтожаете временное после назначения.
Возможно, было бы яснее написать A& operator=(int)
который имел такой же эффект.