КИТА unofficial

Ваши интересы => Викторины и конкурсы => Тема начата: vimmax от Июль 27, 2007, 12:55:16



Название: Искусство программиования (задача 7)
Отправлено: vimmax от Июль 27, 2007, 12:55:16
Меня на собеседовании завалили на вопросе:

1. Можно ли вызвать внутри метода класса:

Код:
delete this;

И что при этом произойдет ?


Название: Re: Искусство программиования (задача 7)
Отправлено: Sochin от Июль 27, 2007, 01:42:14
С++?


Название: Re: Искусство программиования (задача 7)
Отправлено: tendervampire от Июль 27, 2007, 01:47:23
      А можно есть мухоморы? Можно. Но умрешь.

 Компилятор такую инструкцию допустит, что ему. А исполнение команды приведет к ошибке.
Решение получено экспериментальным путем. Компилятор - Майкрософт VC 8.0, но не думаю, что другие компиляторы поведут себя иначе. Если нужно, могу покопать Страуструпа, найти конкретный ответ - почему и как.
 


Название: Re: Искусство программиования (задача 7)
Отправлено: vimmax от Июль 27, 2007, 02:20:20
tendervampire выложи свой код, плиз


Sochin да, это С++.


Название: Re: Искусство программиования (задача 7)
Отправлено: Sochin от Июль 27, 2007, 02:48:00
А что собственно произойти должно? Метод класса это по сути обычная функция, которая неявно получает указатель на объект this. И этот указатель может использоваться внутри функции также как и любой другой указатель. В том числе и  для удаления объекта. Т.е.
Код:
delete this;
произведет вызов деструктора текущего объекта и освобождение памяти. И тут ошибки не будет. Ошибка возникнет тогда когда после удаления объекта будет произведена попытка обращения к атрибутам разрушенного объекта как в данном методе так и в любых других методах.


Название: Re: Искусство программиования (задача 7)
Отправлено: vimmax от Июль 27, 2007, 02:57:14
Sochin отлично +1. правильный ответ. Будет вызван деструктор и класс удалится. Этот прием очень широко применяется в mfc.

Вопрос №2:
В каких случаях этот прием вызовет крах программы?
 (кроме случая описанного Sochin)


Название: Re: Искусство программиования (задача 7)
Отправлено: tendervampire от Июль 27, 2007, 03:02:17
 Тут того кода...
Цитировать
#include <stdio.h>
#include<iostream>
class A
{
public:
  A()
  {
   printf("Отработал конструктор\n");
  }
  ~A()
  {
   printf("Отработал деструктор\n");
  }
  void destr()
  {
   delete this;
  }
  void inf()
  {
   printf("не дождетесь!!\n");
  }
};
void main()
{
 A var;
 var.destr();
// var.inf();
 
 scanf;
}
2 Sochin . Согласен, когда проверял, после отработки делита я еще и следующий метод запускал, только и без вызова метода глючит.


Название: Re: Искусство программиования (задача 7)
Отправлено: vimmax от Июль 27, 2007, 03:03:27
tendervampire Молодца! Ответь на вопрос №2 и получишь награду !!! Это как раз твой случай. НУ ?


Название: Re: Искусство программиования (задача 7)
Отправлено: Sochin от Июль 27, 2007, 03:13:53
после отработки делита я еще и следующий метод запускал, только и без вызова метода глючит.
Глючит потому что в приведенном коде объект создается статически и в методе осуществляется попытка его удаления оператором delete. Это кстати и есть ответ на вопрос №2.


Название: Re: Искусство программиования (задача 7)
Отправлено: vimmax от Июль 27, 2007, 03:17:36
Sochin мда.. Забрал все плюсы.
оператор delete можно применять только к объектам созданным оператором new.


Название: Re: Искусство программиования (задача 7)
Отправлено: tendervampire от Июль 27, 2007, 03:42:09
 
2 Sochin Спасибо за подсказку.
2 vimmax спасибо за интересный вопрос. Так, глядишь, брошу администрирование и вернусь к корням :)


Название: Re: Искусство программиования (задача 7)
Отправлено: Sochin от Июль 27, 2007, 10:16:43
2 vimmax спасибо за интересный вопрос.

Кстати, да, вопрос таки интересный, спасибо. ))


Название: Re: Искусство программиования (задача 7)
Отправлено: EvilMax от Июль 28, 2007, 09:18:12
Вопрос №2:
В каких случаях этот прием вызовет крах программы?
 (кроме случая описанного Sochin)
Нельзя применять этот метод освобждения памяти, если объект является полем другого. Нельзя применять такой метод, если использовался оператор new с синтаксисом размещения: ( new (ptr) Class;  где ptr - указатель на область памяти, где будет размещен экземпляр). Могут быть проблемы, если создавался массив объектов.

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


Название: Re: Искусство программиования (задача 7)
Отправлено: Sochin от Июль 28, 2007, 09:28:18
Проще сказать, когда можно применять этот метод: delete this безопасно, только если мы имеем одиночный экземпляр созданный обычным вызовом new и это последнее обращение к этому экземпляру.
т.е. для общего случая должно быть обеспечено что ни в текущем методе ни выше по стеку вызовов нет больше попыток обращений к этому объекту, в том числе и через другие указатели.