Должен “удалить это” быть названным из членского метода?

В Irssi (на терминальном основанный клиент IRC, не "действительно" язык программирования), $L означает текущую командную строку. Таким образом, можно вызвать переполнение стека ("предел рекурсии максимума хита") с:

/eval $L
20
задан Daniel Daranas 10 June 2013 в 08:33
поделиться

12 ответов

Обычно это плохая идея, но иногда бывает полезно.

Это совершенно безопасно, если вы не используете никакие переменные-члены после удаления, и пока клиенты вызывают это метод понимает, что он может удалить объект.

Хороший пример того, когда это полезно, - если ваш класс использует подсчет ссылок:

void Ref() {
  m_References++;
}

void Deref() {
  m_References--;
  if (m_References == 0) {
    delete this;
  }
}
33
ответ дан 29 November 2019 в 22:42
поделиться

Да, можно, и вот хорошее объяснение того, когда и почему

11
ответ дан 29 November 2019 в 22:42
поделиться

Да, в некоторых случаях это обычное явление.

Подсчет ссылок:

void release() 
{
  cnt--;
  if (cnt == 0) 
    delete this;
}

Программирование графического интерфейса. В некоторых фреймворках, когда пользователь закрывает окно, обычно окно само удаляется.

5
ответ дан 29 November 2019 в 22:42
поделиться

Не без очень веской причины для этого.

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

Это, вероятно, не ожидаемое поведение, поэтому оно может легко привести к неприятным ошибкам.

При этом, как говорится, бывают случаи, когда это подходящие (я видел несколько схем управления памятью с определенными библиотеками, где вы явно создаете методы в классах, которые удаляются сами себя - в первую очередь для языковой совместимости). В целом, я считаю, что это плохая практика.

1
ответ дан 29 November 2019 в 22:42
поделиться

Это часто использовалось во времена MFC. IIRC последнее сообщение, которое получает окно, это WM_NCDESTROY , после чего вы можете вызвать удалить это , конечно, предполагая, что вы были в какой-то форме садистом (хотя сам MFC иногда делал это, я думаю .)

1
ответ дан 29 November 2019 в 22:42
поделиться

Некоторые библиотеки потоков используют ее при реализации автоматического уничтожения при завершении потока.

void Thread::threadFunc()
{
    doRun();

    if(this->destroyOnExit == true)
        delete this;
}
1
ответ дан 29 November 2019 в 22:42
поделиться

Я думаю, что здесь действительно есть 2 вопроса

Можно ли удалить это правильно, вызванное из метода-члена?

Да. Это законно, если вы очень осторожны с использованием.

Следует ли использовать delete в методе-члене?

В очень особых случаях это необходимо. Некоторые типы интеллектуальных указателей, например, используют шаблон удалить этот , чтобы уничтожить указатель. Примеры: CComPtr <> стиль.

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

12
ответ дан 29 November 2019 в 22:42
поделиться

Вы можете сделать это, предоставив его последний элемент в функции-члене, и что после возврата вы забудете, что этот объект когда-либо существовал .... но да, как эта статья спрашивает ... Почему ты бы хотел это сделать? Я не знаю, что говорит стандарт, но это вызывает у меня забавное чувство: P

Я думаю, это немного похоже на использование оператора GOTO, и я лично иногда использую GOTO для очистки ресурсов в C , особенно в исключительных условиях.

Интересно, каковы последствия совместного состояния (нечеткое утверждение, которое я знаю): P

0
ответ дан 29 November 2019 в 22:42
поделиться

Готовимся к голосованию против.

Если это : Нет.
Может ли это технически : Да
Это хорошая идея : Абсолютно нет.
Есть ситуации, которые пригодятся : Конечно. Если вы C ++, foo чрезвычайно силен. Но большинство людей не так хороши. Так что делайте это только в том случае, если с вами работает команда людей, способных выполнить приличную проверку кода.

Почему :
У объекта нет способа узнать, что он был динамически выделен (и, следовательно, требует удаления) или является нормальным объектом (и, следовательно, не должен быть удален), и, следовательно, как он может решить, следует ли его удалить. Таким образом, если объект удаляет сам себя, то, на мой взгляд, что-то ужасно не так с дизайном.

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

5
ответ дан 29 November 2019 в 22:42
поделиться
  1. удалить это нельзя вызвать из функции, не являющейся членом :)
  2. Это плохая идея, пока вы не поймете последствия.
0
ответ дан 29 November 2019 в 22:42
поделиться

Да. Как и во всех ответах, если вы на 100% уверены, что данные класса не будут использоваться после вызова delete, это .

Например, в одном проекте:

void Test()
MyClass * Someclass = new MyClass;
SomeClass->DoYourThing();
SomeClass->KillYourself();
return;

void MyClass::DoYourThing() { return; }
void MyClass::KillYourself() {delete this;}

Очень упрощенное объяснение , проект использовал удалить это; как часть управления памятью для объектов этого типа; их конструктор добавил их в частный список используемых классов этого типа, и удалили себя из этого списка, когда они были уничтожены, а затем удалили себя (этого не было в деструкторе). Любые объекты этого класса, которые не удалились, когда программа достигла своей конечной точки, тогда все имели их эквивалент KillYourself () , вызываемый из статической функции-члена CleanYourself ()

0
ответ дан 29 November 2019 в 22:42
поделиться

Хотя я и не имел прямого отношения к этому потоку, но хотел это прояснить. Мне был задан вопрос, который дал ситуацию:

int* a = new int ;
int* b = a ;
delete a;

Теперь следующее утверждение безопасно?

cout<<*b ;

Мой ответ: После удаления a, место, на которое указывает a, было помечено для удаления, и в любой момент времени оно может быть присвоено какому-либо другому объекту. Следовательно, доступ к значению с помощью b небезопасен, так как оно может быть изменено после его присвоения какому-либо другому объекту.

Примечание: Никакого опускания вниз, пожалуйста, это просто уточнение

.
0
ответ дан 29 November 2019 в 22:42
поделиться
Другие вопросы по тегам:

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