Помощь - Поиск - Пользователи - Календарь
Полная версия: Задачи на знание ООП
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Страницы: 1, 2, 3
Алена
Цитата
Честно говоря не понимаю почему так.
Потому, что этот вариант некорректен по определению. Если бы ты компилировал ЭТО в FPC, например, то получил бы Error 216 или AV. Почему?

А кто тебе сказал, что
getmem(p,sizeof(ob));
инициализирует указатель нулем? Ты что, переопределял где-то HeapFunc? По умолчанию GetMem возвращает ненулевой указатель на выделенную область памяти, а при нехватке памяти инициирует RunTime Error, то есть, корректно получить указатель равный Nil с ее помощью - проблематично.

Если TP "замалчивает" ошибку - это еще не значит, что ее нет. Насколько я знаю, эта тема как раз и создавалась для того, чтобы научить избегать подобных ошибок, а не делать их преднамеренно. Есть гораздо более корректный и красивый способ сделать то, что требовалось по условию. yes2.gif
Bokul

type
pT = ^T;
T = object
end;

pTT=^TT;
TT=object(T)
end;

procedure X(const the_pointer: pT);
begin
if the_pointer=nil then writeln('not assigned');
end;

var
p: ^TT;
mem:longint;
begin
mem:=memavail;
new(p);
X(p);
writeln('Difference: ',mem-memavail);
readln;
end.

volvo
no1.gif Не пойдет... Имелся в виду другой способ... А теперь - о природе данного вопроса, почему собственно я его задал, хотя, казалось бы, предыдущий вопрос еще не решен окончательно? А вот почему. Я как раз это и хотел выяснить, знаешь ли ты, что при таком вызове
X(new(pT, Init));
в процедуру может передаваться NIL (и в каком именно случае это происходит)? Оказалось, что не знаешь... Вот отсюда и вытекает одна из проблем, с которой ты столкнулся в предыдущей задачке, решать которую тебе пришлось "костылями"...

Теперь, с подсказкой, КАК вызывать процедуру, сможешь написать код, который делает то, что требовалось? smile.gif
Bokul
Цитата(volvo @ 12.12.2006 17:34) *

знаешь ли ты, что при таком вызове
X(new(pT, Init));
в процедуру может передаваться NIL (и в каком именно случае это происходит)? Оказалось, что не знаешь...

Даже хуже - я не понимаю почему... Ведь если есть конструктор, должно быть и поле виртуальных методов, а значит размер объекта в куче будет не нулевым. Тогда как new может вернуть nil?
Цитата

Теперь, с подсказкой, КАК вызывать процедуру, сможешь написать код, который делает то, что требовалось? smile.gif

Не понял, о каком коде идет речь? unsure.gif
volvo
Цитата
Не понял, о каком коде идет речь?
О том коде, при добавлении которого в программу (и вызове процедуры так, как я показал), получим сообщение "not assigned"... По умолчанию ты его не получишь, нужно кое-что сделать дополнительно...

Цитата
Даже хуже - я не понимаю почему...
Вот-вот... Я догадался, в чем проблема... А раз ты не понимаешь почему это происходит, то, само собой, не проверяешь и такой возможности, что при выделении памяти под объект "на лету" тебе может вернуться нулевой указатель... Может... Дело все в том, что Constructor - это не совсем простая процедура... Это, скорее, даже не процедура, а функция... И она может возвращать True/False для статических объектов и Nil/{указатель_на_объект} для динамических...
Bokul
Цитата
И она может возвращать True/False для статических объектов и Nil/{указатель_на_объект} для динамических...

Ха, действительно так good.gif Никогда не встречал информации об этом. В каких ситуациях Constructor будет возвращать False, True? Какие преимущества дает использование конструктора для статических объектов?

Цитата
О том коде, при добавлении которого в программу (и вызове процедуры так, как я показал), получим сообщение "not assigned"..

Условие менялось и, чтобы не возникло путаницы переспрошу - с такой процедурой?

procedure X(const the_pointer: pT);
begin
if the_pointer=nil then writeln('not assigned');
end;

volvo
Вот с таким:
procedure X(const the_pointer: pT);
begin
if not assigned(the_pointer) then writeln('not assigned');
end;

Аленка была абсолютна права, я сразу просто забыл поставить not, она же мне и напомнила...
Bokul
Цитата
. В каких ситуациях Constructor будет возвращать False, True? Какие преимущества дает использование конструктора для статических объектов?
А
rolleyes.gif rolleyes.gif rolleyes.gif ???????
Цитата
Вот с таким:

Я же тоже самое написал...
volvo
Цитата
Какие преимущества дает использование конструктора для статических объектов?
blink.gif Попробуй обратиться к методу статического объекта, лучше - виртуальному, чтобы прочувствовать как следует, без предварительного вызова конструктора...

(главное - не запутайся, статический объект - тот, который описывается так:
var obj: TObject;
и соответственно создается в сегменте данных, а динамический - это тот, который создается через New в "куче")
Bokul
Цитата
главное - не запутайся

Правильно заметил - я запутался с терминами. Теперь все ясно.

Почему не отвечаешь на самые интересные вопросы? smile.gif

Я понял, что эта задача сводится к тому, чтобы конструктор вернул false?
Цитата
По умолчанию, когда для динамического экземпляра объекта не
хватает памяти, вызов конструктора, использующий расширенный син-
таксис стандартной процедуры New, генерирует ошибку этапа выпол-
нения 203. Если вы установили функцию обработки ошибки динамичес-
ки распределяемой области, которая вместо стандартного результата
функции 0 возвращает 1, когда выполнить запрос невозможно, вызов
конструктора через New возвращает nil (вместо прерывания програм-
мы).

Восстановление ошибок конструктора
Так что, надо замусорить всю память в куче для решение?
Bokul
Разобрался, даже память не надо использовать, просто в конструкторе вызвать Fail, и все будет хорошо... smile.gif

type
pT=^T;
T=object
constructor init;
destructor done;
end;
constructor T.init;
begin
done;
fail;
end;


destructor T.done;
begin end;

procedure x(const the_pointer:pT);
begin
if the_pointer=nil then
writeln('not assigned');
end;

var mem:longint;
begin
mem:=memavail;
X(new(pT,init));
writeln('Difference: ',mem-memavail);
readln;
end.

Bokul
Значит правильно? smile.gif

Теперь я хотел бы вернутся к вопросу о организации и освобождения с память указателей на один и тот же объект - Сообщение #88.

Как сделать правильное освобождение, чтобы потом не возникло Error 210?
volvo
Цитата
Теперь я хотел бы вернутся к вопросу о организации и освобождения с память указателей на один и тот же объект
Ну что ж... Давай вернемся... smile.gif Только вначале я хотел бы тебя переадресовать вот сюда:

Задачи на знание ООП (сообщение №58)... Здесь ты совершил стратегическую ошибку, выбрав для себя вариант №3 - назначение индексов самому... Я, если честно, на такой вариант не рассчитывал (потому, что я объяснил, что структура представляет собой кортеж, в котором обращение идет не как в списке, чтобы сам объект назначал нумерацию, а нумерация задается мной) - поэтому вот тот вариант, который я имел в виду, когда создавал тему:

Спойлер (Показать/Скрыть)

smile.gif
Bokul
Ясно, все красиво и просто.. smile.gif после того как уже посмотрел... sad.gif
Цитата
Я, если честно, на такой вариант не рассчитывал

А я на функцию copy не рассчитывал... Это специально для нее ты сделал метод make_copy виртуальным?

Ну как, продолжение будет? rolleyes.gif

М
Нет, продолжения не будет... Я, если честно, рассчитывал на бОльшую посещаемость данной темы. Но, как выяснилось, на этом форуме все считают себя достаточно разбирающимися в ООП (только вот непонятно, что ж никто не отвечает на вопросы по этой теме, редко, но все-же появляющиеся в разделе "Задачи"?), для одного человека я поддерживать тему не буду.

Закрыто...

Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.