IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

6 страниц V « < 3 4 5 6 >  
Closed Topic Открыть новую тему 
> Задачи на знание ООП, (только для Турбо-Паскаля 7.0)
Bokul
сообщение 7.12.2006 2:57
Сообщение #81


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


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

Дамм, надо отвыкать использовать универсальное местоимение ... ... smile.gif
Дело в том, что, если мы передадим в этот метод объект без инициализированной VMT, то ошибка этапа компиляции возникнет тут :
typeof(p^)


Цитата
Ты покажи такой ответ, которого можно добиться...


var
obj_int: PTint;
p:pointer;
begin
obj_int := new(PTint,create);
p:=obj_int;
any_arr.count_each(p);
end.


Цитата
Вот я сейчас могу показать, что надо сделать, чтобы произошла именно ошибка №210, а не немедленное закрытие программы, "неправильная инструкция" или еще что-то в этом роде.

Если приведенный выше вариант не правильный, покажи... smile.gif


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.12.2006 3:11
Сообщение #82


Гость






Цитата
ошибка этапа компиляции возникнет тут :
Правда? Даже nil не даст тебе там ошибку... Тем более на этапе компиляции... Достаточно, что тип формального параметра МОЖЕТ содержать указатель на VMT - это гарантирует успешную компиляцию...

Вот мой вариант генерации ошибки 210:
any_arr.count_each(nil);

?
 К началу страницы 
+ Ответить 
Bokul
сообщение 7.12.2006 3:23
Сообщение #83


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
Достаточно, что тип формального параметра МОЖЕТ содержать указатель на VMT - это гарантирует успешную компиляцию...

А существование VMT, гарантирует существование у объекта конструктора, деструктора или хотя бы одного виртуального метода?

Цитата
Вот мой вариант генерации ошибки 210:

TP вылетает, а FreePascal показывает 216-ую... Или это уже как следствие? При отладки в TP, как можна понять, что это 210-ая,? Она же "фатальная"?

А мой вариант не правильный?

Сообщение отредактировано: Bokul - 7.12.2006 3:46


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.12.2006 9:56
Сообщение #84


Гость






smile.gif Кстати, я нашел у тебя еще кое-что не совсем корректное... Смотри:

function TArr.set_index(const p: PT):boolean;
begin
inc(num);
if num<= maxSize then
begin
arr[num]:=p;
set_index:=true;
end
else
begin
dec(num);
dispose(p,done);
set_index:=false;
end;
end;
- полностью твой код, у меня этого просто не было... А теперь представь, что мне надо первые 10 элементов установить в значение 3.5 - неужели для этого я должен инициализировать переменную 10 раз... Я сделал так:
  obj_float := new(PTfloat,create);
obj_float^.value := 3.5;
for i:=1 to 10 do
begin
if obj_float <> nil then { <--- Вот эту проверку, кстати, пользователь, делать не должен ... }
any_arr.set_index(obj_float);
end;
и что я получу, догадайся?

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

Цитата
При отладки в TP, как можна понять, что это 210-ая,? Она же "фатальная"?
У меня в верхней строке экрана сообщается, какая ошибка произошла, ничего никуда не вылетает...

Цитата
А существование VMT, гарантирует существование у объекта конструктора, деструктора или хотя бы одного виртуального метода?
Существование VMT гарантируется вызовом конструктора. А наличие деструктора и виртуальных методов (при существовании VMT) - это уже проблема программиста... Они могут быть, а могут не быть - это синтаксисом не оговорено...

С другой стороны, даже наличие у объекта 10 виртуальных методов тебе ничего не даст, если ты НЕ сконструировал экземпляр как положено, т.е. можно сказать так: наличие правильной VMT не гарантируется ничем, кроме вызова конструктора... А дело-то все в том, что TypeOf во время компиляции не может проверить правильность таблиц виртуальных методов, ибо эти самые таблицы только в RunTime создаются...
 К началу страницы 
+ Ответить 
Bokul
сообщение 8.12.2006 4:42
Сообщение #85


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
и что я получу, догадайся?

Большую толстую ошибку smile.gif
Получаем 10 указателей на один и тот же объект, что есть не очень хорошо, так как потом мы попытаемся их все освободить из памяти при помощи виртуального деструктора, но после первого "освобождения", нам останется 9 указателей на объект без VMT, что при последующим вызове виртуального done вызовет ошибку 210.
Цитата
а проверку, которую я показал делать пользователю класса действительно не совсем корректно, хотя даже это не помогло...

Все понял. Мне вообще интересует вопрос о том, что должен знать и не знать объект.
Цитата
А дело-то все в том, что TypeOf во время компиляции не может проверить правильность таблиц виртуальных методов

Я тут уже задавал вопрос, но так и не услышал ответа: что на самом деле делает TypeOf? Возвращает значения поля виртуальных объектов у объекта?
А как она может проверить правильность этих таблиц? Ведь вся инфа об объекте хранится именно там?
Цитата
наличие правильной VMT не гарантируется ничем, кроме вызова конструктора...

Я так и не понял (вернее опять запутался) что делает конструктор. Я думал, что он заполняет ПВМ (поле виртуальных методов), а в построении таблиц он не участвует.

Вопрос Из чего состоит размер объекта? Только из его полей + , при условии существования конструктора, 4 байтов для ПВМ?


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 8.12.2006 11:50
Сообщение #86


Гость






Цитата
Я так и не понял (вернее опять запутался) что делает конструктор.

Цитата(http://sizov.boom.ru/books/turbo6/tpash.htm)
Как упомянуто ранее, констрактор объектного типа содержит специальный код, который сохраняет смещение VMT объектного типа в инициализируемом экземпляре.


Цитата
Я думал, что он заполняет ПВМ (поле виртуальных методов), а в построении таблиц он не участвует.
Я где-то сказал, что он участвует в построении таблиц? blink.gif Я сказал, что до тех пор, пока ты не вызовешь конструктор, с VMT правильно работать не получится, следовательно ни на SizeOf ни на TypeOf полагаться нельзя, ибо они как раз работают с тем адресом, который этим самым конструктором заносится в поле экземпляра объекта...


Цитата
Из чего состоит размер объекта? Только из его полей + , при условии существования конструктора, 4 байтов для ПВМ?

Во-первых, я уже давал тебе ссылку, а во-вторых - не 4-х а 2-х байтов (в поле хранится только 16-битное смещение, ибо компилятору, а следовательно и программе, прекрасно известно, что VMT хранится в сегменте данных, так зачем за собой таскать еще 2 лишних байта? Помнишь мою программу с елкой? На сегодняшний день в ней - работа над программой продолжается - до 3000 объектов с виртуальными функциями одновременно висят в памяти, если каждый из них будет захватывать 2 "лишних" байта - то 6К у тебя вычеркнуто из размера кучи, а она не такая уж и большая, чтобы так вольно с ней обращаться...)

Цитата
Мне вообще интересует вопрос о том, что должен знать и не знать объект.
Объект должен знать ровно столько, сколько ему необходимо для того, чтобы корректно работать... В частности, информация, как был создан указатель на объект, передаваемый ему в качестве параметра (операция @, примененная к статическому объекту, взятие Addr от типизированной константы объектного типа, или конструирование прямо "on the fly" через New) - совершенно не должна его интересовать... С любым из этих случаев работа должна производиться одинаково, для этого у тебя и объявлен тип формального параметра...

Цитата
что на самом деле делает TypeOf? Возвращает значения поля виртуальных объектов у объекта?
Возвращает нормализованный указатель на VMT для заданного типа/экземпляра (т.о., если эти указатели равны, то экземпляры принадлежат к одному и тому же типу)...
Цитата
Ведь вся инфа об объекте хранится именно там?
Там хранятся только адреса виртуальных процедур/функций, это еще не ВСЯ информация, а только ее часть.
 К началу страницы 
+ Ответить 
Bokul
сообщение 9.12.2006 1:11
Сообщение #87


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Спасибо, теоретическая часть укрепилась. good.gif
То как там по поводу
Цитата
Большой толстой ошибки:
Получаем 10 указателей на один и тот же объект, что есть не очень хорошо, так как потом мы попытаемся их все освободить из памяти при помощи виртуального деструктора, но после первого "освобождения", нам останется 9 указателей на объект без VMT, что при последующим вызове виртуального done вызовет ошибку 210.

Правильно?

Сообщение отредактировано: Bokul - 9.12.2006 1:12


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 9.12.2006 1:43
Сообщение #88


Гость






Цитата
Правильно?
Не совсем... В том фрагменте, который я тебе привел (пост №84), происходит следующее: я получил указатель на объект. Здесь все по правилам... Дальше я хочу просто один и тот же указатель 10 раз передать в функцию, чтобы 10 последовательных ячеек были заполнены одинаковым значением.. И что? Твоя реализация мне этого не позволяет, потому что после первого же Dispose указатель становится, скажем так, невалидным (вообще-то это определение из С++, но очень оно мне нравится, я использую его и здесь)... Хотя указатель передается в функцию через спецификатор Const, все-же Dispose к нему применяется, а значит, удаляется связь экземпляра с VMT, что перечеркивает возможность дальнейшего использования как этого объекта, так и указателя на него...

А надо бы такое (я про использование одного указателя для нескольких ячеек) позволять... Что для этого придется сделать? Есть мысли?

Кстати, еще один вопрос, по ходу действия, у меня к тебе (ибо отвечаешь и интересуешься этой темой только ты, остальные видимо, знают все в совершенстве) : допустим, есть фрагмент кода:

type
pT = ^T;
T = object
...
end;

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

var
p: ^T;
...
X( {что-то} )
...
Можно ли добиться того, чтобы при каких-то условиях было выведено сообщение "not assigned", и если ответ = "да", то перечисли все способы, которые ты можешь себе представить для этого (ничего не меняя внутри самой процедуры X, только снаружи), а если "нет" - то почему? smile.gif
 К началу страницы 
+ Ответить 
Bokul
сообщение 9.12.2006 2:30
Сообщение #89


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
procedure X(const the_pointer: pT);

А сначала ведь был Var wink.gif
Цитата
Хотя указатель передается в функцию через спецификатор Const, все-же Dispose к нему применяется, а значит, удаляется связь экземпляра с VMT

В каком смысле удаляется? wub.gif Я понимаю, что память, ранее зарезервированная под объект, уже больше не связанна с указателем на него (объект), и что в любое время она может быть переписана, но ведь ПВМ все-равно продолжает указывать на VMT объекта.
Цитата
А надо бы такое (я про использование одного указателя для нескольких ячеек) позволять... Что для этого придется сделать? Есть мысли?

Сделать только один указатель связанный с самим объектом, остальные будут связанные с ним... wacko.gif В общем над этим вопросом думаю 61 поста, нормальных идей не было...
Цитата
Можно ли добиться того, чтобы при каких-то условиях было выведено сообщение "not assigned", и если ответ = "да", то перечисли все способы, которые ты можешь себе представить для этого (ничего не меняя внутри самой процедуры X, только снаружи), а если "нет" - то почему?

if not('да') and not('не') then
writeln('не знаю ')

Сообщение отредактировано: Bokul - 9.12.2006 2:36


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Bokul
сообщение 9.12.2006 7:26
Сообщение #90


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
Можно ли добиться того, чтобы при каких-то условиях было выведено сообщение "not assigned", и если ответ = "да", то перечисли все способы, которые ты можешь себе представить для этого (ничего не меняя внутри самой процедуры X, только снаружи), а если "нет" - то почему?

Ха, красиво! good.gif Я сначала перепутал как действует assigned, но ничего, разобрался. Не знаю, можно ли было использовать компилятор, но я использовал, в следующий раз оговаривай, пожалуйста, этот вопрос. smile.gif

И собственно ответ:
p:^T

этот указатель ссылается на место в куче, где размещены поля объекта T, а значит, если их нету - то й указатель будет nil-овым smile.gif . Выходит, что у нас есть две возможности обеспечить работу для p:
1 Добавить в объект T любое поле.
2 Создать ПВТ.
Вот их реализация:
Цитата
1 Добавить в объект T любое поле.


type
T = object
b:byte;
end;


2 Создать ПВТ.

Выбираем один из 3 способов:
через конструктор:

type
T = object
constructor init;
end;

constructor t.init;
begin end;



через деструктор:

type
T = object
destructor done;
end;

destructor t.done;;
begin end;



и виртуальный метод:

type
T = object
procedure VirtualMethod; virtual;
end;

procedure T.VirtualMethod;
begin end;





--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 9.12.2006 12:45
Сообщение #91


Гость






Я не спрашивал, как обеспечить то, что P будет работать... Я спросил - может ли процедура напечатать сообщение...
 К началу страницы 
+ Ответить 
Bokul
сообщение 9.12.2006 18:52
Сообщение #92


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
Я не спрашивал, как обеспечить то, что P будет работать... Я спросил - может ли процедура напечатать сообщение...

Может, забыл дописать еще пару строчек.
Выбираем один из методов создания поля (описанных выше), а потом -

var
p: ^T;
begin
new(p);
X(p);
end.



Сообщение отредактировано: Bokul - 9.12.2006 18:53


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Алена
сообщение 10.12.2006 1:06
Сообщение #93


Гость






Пока volvo не будет - я продолжу за него, хорошо?

Вопрос немного меняется: пост №88 - процедуру изменяем вот так:
procedure X(const the_pointer: pT);
begin
if NOT assigned(the_pointer) then writeln('not assigned');
end;

Задача - не используя в программе переменных типа pT (за исключением формального параметра процедуры) заставить эту самую процедуру напечатать "not assigned"... Если есть несколько способов сделать это - приведите их ВСЕ (ответы принимаются в виде работоспособного кода, а не просто отдельными вставками "а если сделать то-то и то-то")
 К началу страницы 
+ Ответить 
Bokul
сообщение 10.12.2006 3:05
Сообщение #94


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
Пока volvo не будет - я продолжу за него, хорошо?

Если он и не против, то почему бы и нет smile.gif
Цитата
Вопрос немного меняется

Подожди. То, что я по тому вопросу написал, правильно?


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Алена
сообщение 10.12.2006 9:46
Сообщение #95


Гость






По тому вопросу - правильно, но там он просто ошибся, и не поставил сразу NOT в процедуру... Весь смысл был как раз в том, чтобы сделать такой вариант задания, который привела я...
 К началу страницы 
+ Ответить 
Bokul
сообщение 10.12.2006 19:26
Сообщение #96


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
По тому вопросу - правильно, но там он просто ошибся, и не поставил сразу NOT в процедуру...

Откуда такая увереность? wink.gif
Цитата
Весь смысл был как раз в том, чтобы сделать такой вариант задания, который привела я...

Не знаю, то показалось сложнее

type
pT = ^T;
T = object
end;

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

var
p: ^T;
begin
X(nil);
end.




--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Алена
сообщение 10.12.2006 19:36
Сообщение #97


Гость






Еще варианты будут?

Если нет, то я добавляю еще одно ограничение - на использование nil ... Это слово встречаться в программе не должно (равно, как и приведение к нему, вроде X(Pointer(0)))

Your turn smile.gif
 К началу страницы 
+ Ответить 
Bokul
сообщение 10.12.2006 20:13
Сообщение #98


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата

Еще варианты будут?
Если нет, то я добавляю еще одно ограничение

lol.gif lol.gif lol.gif
Цитата
Your turn

d'accord smile.gif
Паскаль, вроде, сам по-началу делает все указатели равным nil...

type
pT = ^T;
T = object
end;

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

var
p: ^T;
begin
X(p);
readln;
end.




--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Алена
сообщение 10.12.2006 21:12
Сообщение #99


Гость






А внимательно прочитать предыдущие посты - никак?

Цитата
Задача - не используя в программе переменных типа pT (за исключением формального параметра процедуры)


Я надеюсь, не надо говорить, что ^T и pT это одно и то же? Иначе никакие задачи давать просто невозможно, ибо надо давать также 20 страниц описаний, что считается нарушением, а что нет... Этого я делать не буду...

Не принято ... Кроме того, изначальное присвоение nil - это компиляторозависимо, и полагаться на это просто опасно...

Сообщение отредактировано: Алена - 10.12.2006 21:13
 К началу страницы 
+ Ответить 
Bokul
сообщение 11.12.2006 2:47
Сообщение #100


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Вот:

type
pT=^t;
T=object
constructor init;
end;
constructor T.init;
begin end;

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

var p:pointer;
ob:t;
begin
p:=@p;{свяжем p с любым адресом}
getmem(p,sizeof(ob));{p:=nil}
x(p);
readln;
end.


Честно говоря не понимаю почему так. wacko.gif Если на месте ob поставить t, ничего не получится. Почему?


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

6 страниц V « < 3 4 5 6 >
Closed Topic Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 18.07.2025 20:51
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"