Re[2]: Уничтожение лок. переменных!!!???
От: WFrag США  
Дата: 05.10.03 12:52
Оценка:
Здравствуйте, MagIH, Вы писали:

MIH>>Всё правильно. За исключением того, что смысла в таком коде мало. А как м почему это работает объясняется легко. В нескольких письмах я тут видел ссылки на стандарт C++. Но если Вы читали стандарт, господа, то там чётко разделяются физический (как что-то должно работать) и логический (что это означает) уровни. Отсюда и путанница. Про оператор delete и про деструктор часто говорят, что они "разрушают" объект. Кстати — а в чём тогда разница между ними? Ответ прост — деструктор, в соответствии со стандартом, это ФУНКЦИЯ, вызываемая перед разрушением объекта (заметьте отличие от "функция разрушающая объект"). Стандарт так же чётко и ясно оговариват время жизни объекта (то есть его состояния в памяти) и условия, когда деструктор будет вызван автоматически (оператор delete, разрушение переменных в стеке по выходу из функции, разрушение членов данных объекта, разрушение глобальных переменых...). При этом, Вы имеете полное (закреплённое стандартом) право вызывать деструктор, как и любую другую функцию, в течение времени жизни объекта сколько угодно раз. И ничего с самим "объектом" = "состоянием объекта" = "областью памяти, занимаемая данными-членами класса объекта" не произойдет (кроме того, что вы сами явно опрелили в деструкторе, как и в любой другой функции). Поэтому то данный пример и работает. Деструктор то просто выводит строку на экран. Так что объект то и не догадывается, что его пытались прикончить... Кстати во всех примерах где возникаяли явные RunTime ошибки — в деструкторе объект портился явно, так, что использование его переменных или повторный вызов деструктора при разрушении объекта (в "стандартной" ситуации) и вызывало сообщение об ошибке.


Гон. Вот тупое опровержение (все VC, до которых дотянулись руки — VC6.0, VC7.0, VC7.1):

#include <iostream>

struct A
{
    virtual ~A() { } // Типа не портим объект явно.
    virtual void func() = 0;
};

struct B : public A
{
    virtual void func() { std::cout << "Yo!" << std::endl; }
};

int main()
{
    A& a = B();
    a.~A(); // Деструктор типа нифига не делает, объекту все параллельно. ;)
    a.func(); // Ооопс. А вот и нет!
}


MIH>> Теперь об операторе delete. Он отличается тем, что делает два действия — вызывает деструктор и затем — освобождает память, выделнную под переменные объекта (впрочем оговорюсь, что delete может быть переопределён и делать что-то иное).


Оператор delete переопределен не может быть. Может быть переопределена функция (ее еще иногда называеют операторной функцией) delete. Оператор delete делает всегда одну и ту же последовательность действий — вызов деструктора, вызов соответствующей операторной функции. Вроде так.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.