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

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

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

6 страниц V « < 3 4 5 6 >  
Closed Topic Открыть новую тему 
> Задачи на знание ООП, (только для Турбо-Паскаля 7.0)
сообщение
Сообщение #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 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #82


Гость






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

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

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


Гуру
*****

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

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


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

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

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

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

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

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


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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 создаются...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #85


Гуру
*****

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

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


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

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

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

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

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

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


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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 для заданного типа/экземпляра (т.о., если эти указатели равны, то экземпляры принадлежат к одному и тому же типу)...
Цитата
Ведь вся инфа об объекте хранится именно там?
Там хранятся только адреса виртуальных процедур/функций, это еще не ВСЯ информация, а только ее часть.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #87


Гуру
*****

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

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


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

Правильно?

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


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


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


Гость






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


Гуру
*****

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

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


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

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

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



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


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


Гость






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

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

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


Гуру
*****

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

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


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

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

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


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


Гость






По тому вопросу - правильно, но там он просто ошибся, и не поставил сразу NOT в процедуру... Весь смысл был как раз в том, чтобы сделать такой вариант задания, который привела я...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #97


Гость






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

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

Your turn smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #99


Гость






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

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


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

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

Сообщение отредактировано: Алена -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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

 





- Текстовая версия 27.04.2024 7:20
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name