Это в порядке для использования “удаляет это” для удаления текущего объекта?

Стоит упомянуть, что обратная совместимость несет собственные расходы. В некоторых случаях почти невозможно развить язык идеальным способом, если 100%-я обратная совместимость требуется. Реализация Java дженериков (который стирает информацию о типе во время компиляции, чтобы быть backwardly-совместимой) является хорошим примером того, как реализование опций с 100%-й обратной совместимостью может привести к субоптимальной функции языка.

Так свободно разговор, это может свестись к выбору между плохо реализованной новой опцией, это backwardly совместимый, или приятно реализованная новая опция, которая это не. Во многих случаях последний является лучшим выбором, особенно если существуют инструменты, которые могут автоматически перевести несовместимый код.

7
задан Mechanical snail 25 July 2012 в 23:39
поделиться

8 ответов

Если вызывается деструктор узла, значит, он уже находится в процессе удаления. Таким образом, удаление не имеет смысла внутри вашего деструктора узла.

Также это неверно:

while (temp->next() != NULL)
{
     delete temp;
     temp = temp->next();
}

Вместо этого вы должны поместить temp-> next () во временную переменную. В противном случае вы обращаетесь к удаленной памяти.

Примерно так:

DoublyLinkedList::~DoublyLinkedList
{
  Node *temp = first();
  while (temp != NULL)
  {
       Node *temp2 = temp->next();
       delete temp;
       temp = temp2;
  }
}
17
ответ дан 6 December 2019 в 06:25
поделиться

В настоящее время ваш код вызовет нарушение прав доступа, поскольку вторая из следующих строк явно обращается к освобожденной памяти:

delete temp;
temp = temp->next();

Если вы хотите рекурсивно удалить структуру, вам нужно что-то вроде этого:

DoublyLinkedList::~DoublyLinkedList
{
    Node *temp = first();
    delete temp;
}

Node::~Node
{
   if(this->next() != NULL) delete this->next();
}
4
ответ дан 6 December 2019 в 06:25
поделиться

удалить это; вызовет деструктор текущего объекта. В том случае, если вы звоните, удалите это; в деструкторе, то деструктор будет вызываться бесконечно до сбоя.

1
ответ дан 6 December 2019 в 06:25
поделиться

Прежде всего: я очень, очень надеюсь, что это домашнее задание, данное вам, чтобы понять двусвязный список. В противном случае нет причин использовать это вместо std :: list . При этом:

Нет, удалить этот в dtor всегда неправильно, так как dtor вызывается, когда this находится в состоянии удаления.

Кроме того, хотя

delete temp;
temp = temp->next();

случайно может работать, это определенно неверно, поскольку при попытке доступа к temp-> next () , temp уже удален, поэтому вы должен вызывать на нем функцию-член. Это вызывает так называемое «неопределенное поведение». (Вкратце: он может делать то, что вы хотите, но с тем же успехом он может терпеть неудачу всегда или спорадически, или только тогда, когда пятница, 13-е, совпадает с новолунием. Это может также вызвать на вас очень неприятных назальных демонов.)

Обратите внимание, что вы можете решить обе проблемы, удалив следующий узел в dtor вашего узла:

Node::~Node()
{
   delete next();
}

Таким образом, ваш список dtor станет очень простым тоже:

DoublyLinkedList::~DoublyLinkedList()
{
    delete first();
}

Мне кажется, что именно для этого были изобретены dtors, поэтому, за исключением того факта, что в настоящее время никто не должен писать свои собственные типы связанных списков, мне кажется, что это решение C ++ к твоей проблеме.

мне кажется, что это решение вашей проблемы на C ++.

мне кажется, что это решение вашей проблемы на C ++.

2
ответ дан 6 December 2019 в 06:25
поделиться

Приведенный выше код вызовет Node :: ~ Node () дважды. (в «delete temp» и в Node :: ~ Node ())

Node :: ~ Node () не должен вызывать «удалить это» (иначе ваша программа выйдет из строя)

ps. цикл while в вашем коде работать не будет. Это приведет к разыменованию недопустимого указателя. Вы должны сначала скопировать значение temp-> next, а затем уничтожить указатель temp.

0
ответ дан 6 December 2019 в 06:25
поделиться

В общем, деструктор должен просто беспокоиться об удалении (или освобождении, если вы используете C или malloc) любой памяти, выделенной специально для вашего объекта. Удаление указателя на ваш объект всегда будет осуществляться ОС, и вам не нужно ни о чем беспокоиться об этой части.

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

Между прочим, то же самое происходит с подклассом - если у вас есть класс A, и класс B: public A, тогда, когда вы выполняете new B (), сначала выполняется конструктор A, а затем конструктор B; при уничтожении сначала выполняется деструктор B, а затем A. Я почти уверен, что вам НЕ стоит об этом беспокоиться - C ++ позаботится об этом за вас. Поэтому не пытайтесь найти способ вызвать удаление в суперклассе.

тогда ОС управляет фактическим освобождением памяти, когда поток управления выпадает из деструктора.

Между прочим, то же самое происходит с подклассами - если у вас есть класс A и класс B: public A, то когда вы выполните новый B (), сначала выполняется конструктор A, затем конструктор B; при уничтожении сначала выполняется деструктор B, а затем A. Я почти уверен, что вам НЕ стоит об этом беспокоиться - C ++ позаботится об этом за вас. Поэтому не пытайтесь найти способ вызвать удаление в суперклассе.

тогда ОС управляет фактическим освобождением памяти, когда поток управления выпадает из деструктора.

Между прочим, то же самое происходит с подклассами - если у вас есть класс A и класс B: public A, то когда вы выполните новый B (), сначала выполняется конструктор A, затем конструктор B; при уничтожении сначала выполняется деструктор B, а затем A. Я почти уверен, что вам НЕ стоит об этом беспокоиться - C ++ позаботится об этом за вас. Поэтому не пытайтесь найти способ вызвать удаление в суперклассе.

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

Первым выполняется деструктор s, за которым следуют A. Я совершенно уверен, что вам НЕ стоит об этом беспокоиться - C ++ позаботится об этом за вас. Поэтому не пытайтесь найти способ вызвать удаление в суперклассе.

0
ответ дан 6 December 2019 в 06:25
поделиться

Ни в коем случае не следует делать то и другое.

Это

DoublyLinkedList::~DoublyLinkedList
{
    Node *temp = first();
    while (temp->next() != NULL)
    {
        delete temp;
        temp = temp->next();
    }
}

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

DoublyLinkedList::~DoublyLinkedList
{
    Node *temp = first();
    while( temp != NULL)
    {
        Node* next = temp->next();
        delete temp;
        temp = next;
    }
}

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

0
ответ дан 6 December 2019 в 06:25
поделиться

Нет, вы не должны удалять этот из деструктора. Деструктор вызывается из-за оператора удаления (или выходит за пределы области видимости), и это, скорее всего, приведет к некоторому сбою.

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

4
ответ дан 6 December 2019 в 06:25
поделиться
Другие вопросы по тегам:

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