Удаляют, это позволило?

Это позволяется delete this; если оператор удаления является последним оператором, который будет выполняться на том экземпляре класса? Конечно, я уверен что объект, представленный this- указатель newly-created.

Я думаю о чем-то вроде этого:

void SomeModule::doStuff()
{
    // in the controller, "this" object of SomeModule is the "current module"
    // now, if I want to switch over to a new Module, eg:

    controller->setWorkingModule(new OtherModule());

    // since the new "OtherModule" object will take the lead, 
    // I want to get rid of this "SomeModule" object:

    delete this;
}

Я могу сделать это?

225
задан Rakete1111 24 August 2016 в 00:46
поделиться

6 ответов

В C++ FAQ Lite есть статья специально для этого

Думаю, эта цитата хорошо подводит итог

Пока вы осторожны, объект может совершить самоубийство (удалите это).

231
ответ дан 23 November 2019 в 03:55
поделиться

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

void IMyInterface::Release()
{
    --instanceCount;
    if(instanceCount == 0)
        delete this;
}
14
ответ дан 23 November 2019 в 03:55
поделиться

Разрешено (только после этого не использовать объект), но на практике я бы не стал писать такой код. Я думаю, что удалить это должно появляться только в функциях, которые вызывали release или Release и выглядят так: void release () {ref--; если (ref <1) удалите это; } .

20
ответ дан 23 November 2019 в 03:55
поделиться

Вы можете это сделать. Однако вы не можете назначить это. Таким образом, причина, по которой вы это делаете: «Я хочу изменить точку зрения», кажется очень сомнительной. На мой взгляд, лучшим методом было бы, чтобы объект, содержащий представление, заменил это представление.

Конечно, вы используете объекты RAII, и поэтому вам вообще не нужно вызывать удаление ... верно?

7
ответ дан 23 November 2019 в 03:55
поделиться

Да, удалить это; определил результаты, если (как вы отметили) вы гарантируете, что объект был выделен динамически, и (конечно) никогда не пытайтесь использовать объект после его уничтожения. За прошедшие годы было задано много вопросов о том, что конкретно говорится в стандарте об удалении , , а не об удалении какого-либо другого указателя. Ответ на это довольно короткий и простой: он ни о чем не говорит. Он просто говорит, что операнд delete должен быть выражением, которое обозначает указатель на объект или массив объектов. В нем довольно подробно рассказывается о таких вещах, как то, как он определяет, какую (если есть) функцию освобождения памяти для освобождения памяти, но весь раздел о delete (§ [expr.delete]) не делает этого. не упоминать удалить это; конкретно вообще.В разделе о деструкторах упоминается удалить это в одном месте (§ [class.dtor] / 13):

В точке определения виртуального деструктора (включая неявное определение (15.8)), функция освобождения массива, не являющаяся массивом, определяется, как если бы выражение delete this появилось в невиртуальном деструкторе класса деструктора (см. 8.3.5).

Это имеет тенденцию поддерживать идею о том, что стандарт считает удалить это; действительным - если бы он был недопустимым, его тип не имел бы смысла. Это единственное место, где стандарт упоминает удалить это; вообще, насколько мне известно.

В любом случае, некоторые считают удалить это мерзким приемом и говорят всем, кто будет их слушать, что этого следует избегать. Одна из часто упоминаемых проблем - это сложность обеспечения того, чтобы объекты класса всегда выделялись только динамически. Другие считают это вполне разумным идиомой и используют ее постоянно. Лично я где-то посередине: я редко использую его, но без колебаний делаю это, когда кажется, что это правильный инструмент для работы.

В первый раз вы используете эту технику с объектом, у которого есть почти полностью собственная жизнь. Одним из примеров, которые привел Джеймс Канце, была система биллинга / отслеживания, над которой он работал для телефонной компании. Когда вы начинаете звонить, что-то принимает к сведению это и создает объект phone_call .С этого момента объект phone_call обрабатывает детали телефонного звонка (установление соединения при наборе номера, добавление записи в базу данных, чтобы сказать, когда начался звонок, возможно подключение большего количества людей, если вы сделаете конференц-связь и т. д.). Когда последний собеседник повесил трубку, объект phone_call выполняет свою последнюю учетную запись (например, добавляет запись в базу данных, чтобы сообщить, когда вы положили трубку, чтобы они могли вычислите, как долго длился ваш звонок), а затем уничтожает себя. Время жизни объекта phone_call зависит от того, когда первый человек начинает вызов и когда последние люди прекращают вызов - с точки зрения остальной системы, это в основном совершенно произвольно, поэтому вы не может связать его с какой-либо лексической областью в коде или чем-либо в этом порядке.

Для всех, кого может волновать, насколько надежным может быть такой вид кодирования: если вы звоните по телефону в любую часть Европы, из нее или через нее, есть довольно хороший шанс, что с этим справятся (по крайней мере, частично ) с помощью кода, который делает именно это.

83
ответ дан 23 November 2019 в 03:55
поделиться

Если это вас пугает, есть совершенно законный способ взлома:

void myclass::delete_me()
{
    std::unique_ptr<myclass> bye_bye(this);
}

Я думаю, что удалить это - это идиоматический C ++, и я представляю это только как любопытство.

Есть случай, когда эта конструкция действительно полезна - вы можете удалить объект после генерации исключения, которому требуются данные члена из объекта. Объект остается в силе до тех пор, пока не будет произведен бросок.

void myclass::throw_error()
{
    std::unique_ptr<myclass> bye_bye(this);
    throw std::runtime_exception(this->error_msg);
}

Примечание: если вы используете компилятор старше C ++ 11, вы можете использовать std :: auto_ptr вместо std :: unique_ptr , он сделает то же самое. .

46
ответ дан 23 November 2019 в 03:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: