Здравствуйте, 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 делает всегда одну и ту же последовательность действий — вызов деструктора, вызов соответствующей операторной функции. Вроде так.