1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Можно ли у наследнике переопределить тип унаследованного поля?
type TA=object pole:byte; end;
TB=object(TA) pole:integer; end;
Компилятор ругается и Faq'e написанно, что нельзя, но неужели нету нормального способа использовать вот этот модуль Односвязный список с использованием ООП (сообщения №5) без ковыряния в его коде, понимая что надо будет изменить некоторые процедуры.
Цитата
В качестве базового типа для всех структур приведенных ниже используется тип Integer (который при желании можно заменить на любой встроенный тип Паскаля: числовой, логический, символьный или строковый).
Эта фраза дает оптимистические надежды. P.S можно ли давать ссылку на конкретное сообщения в теме?
Сообщение отредактировано: volvo -
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
Можно ли у наследнике переопределить тип унаследованного поля?
Нет... ПЕРЕопределить ничего из того, что касается полей нельзя...
Цитата
Эта фраза дает оптимистические надежды.
Реализация эти оптимистические надежды превратит в пессимистические... Не все так просто, за возможность использования любого типа ты должен, что понятно, платить... Чем? Размером объекта... Ищи у меня на сайте рабочую реализацию объектов, работающих с любым типом данных...
Как вариант - супермодератору смотреть на название форума, если не затруднит!
Устное предупреждение... Дальнейшее подобное поведение будет рассматриваться, как флуд. Со всеми вытекающими... Для Дельфи/FPC/С# есть отдельный форум. Автор задает вопрос в форуме Задачи...
Прошу прощения - промазал, а целился в 32 битные компиляторы (Fpc), зато получил извращенный вариант для обычного паскаля. klem4, спасибо, +1 за "изврат" .
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
Можно ли у наследнике переопределить тип унаследованного поля?
Именно так, если я не ошибаюсь, стоял вопрос? И что? Bokul, ты считаешь, что работа с ОДНИМ и тем же полем, расположенным в родителе через переопределенный метод - это аналог того, что ты спросил? Это во-первых...
Во-вторых: код не учитывает "золотое правило ООП": потомок инициализируется через конструктор предка! Иначе будут проблемы. Если надо, могу привести пример, когда ЭТОТ же код (если в него добавить 10 строк, ничего в существующих строках не меняя) при запуске будет зависать... А если инициализировать TB через TA, то... утечка, простите...
procedure getmem(var p: pointer; size: integer); begin
if NotEnoughMemory then p := nil else system.getmem(p, size);
end;
type
TA = object
p: Pointer;
constructor Create; function GetP: Byte;
end;
TB = Object(TA)
constructor Create; function GetP: Integer; end;
constructor TA.Create; var pB : ^Byte; begin if notEnoughMemory then Fail;
GetMem(pB, sizeof(Byte)); p := pB; Byte(p^) := 3; end;
constructor TB.Create; var pI: ^Integer; begin GetMem(pI, sizeof(Integer)); p := pI; Integer(p^) := 5; end;
function TA.GetP: Byte; begin GetP := Byte(p^); end;
function TB.GetP: Integer; begin GetP := Integer(p^); end;
var
a: TA; b: TB; begin a.Create; // big memory request NotEnoughMemory := true;
b.Create; writeln(a.GetP); writeln(b.GetP);
readln; end.
Объясняю ситуацию: инициализировали объект A, потом был запущен какой-то цикл, просящий память у система... Система отдает в этом цикле всю кучу... Я не стал делать сам этот цикл, я смоделировал ситуацию, введя флаг NotEnoughMemory, показывающий наличие/отсутствие свободной памяти... Как только память закончилась, флаг переброшен в True... Теперь вспоминаем, как работает GetMem: если HeapFunc возвращает 1, то при недостатке памяти указатель - нулевой, если 2, то при недостатке памяти система повторяет запрос на распределение памяти ... Ты в своей программе не знаешь, что возвращает HeapFunc, ибо ее подмена может быть сделана в любом подключаемом в Uses модуле... Допустим, возвращает 1 - тогда системный GetMem работает аналогично моему - возвращает Nil... Результат - RunTime Error... Если HeapFunc будет возвращать 2, получишь бесконечную очередь запросов на выделение памяти и отказов, опять запрос - отказ...
Цитата
Поможет ?
Поможет, только не в том, что ошибки не будет, а в том, что ошибка будет централизованно (в самом первом объекте цепочки наследования) обрабатываться, и экземпляр объекта B просто не будет создан...
Именно так, если я не ошибаюсь, стоял вопрос? И что? Bokul, ты считаешь, что работа с ОДНИМ и тем же полем, расположенным в родителе через переопределенный метод - это аналог того, что ты спросил? Это во-первых...
Да ты прав, но все же на том этапе изучения работы с объектами, на котором нахожусь я, интересно по больше узнать о технике работы с ними, о всях таких "извратах". А за золотое правило и пример спасибо, +1.
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
Может я конечно что-то не понял, но всеже, Volvo, ты согласишься с тем что ошибка в моей программе связана не с какими-то аглоритмическими/логическими огрехами, а с если так можно сказать издержками программирования. Программе для работы нужна динамическая пямять, если ее нет, будет ошибка. Это логично.
--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
Программе для работы нужна динамическая пямять, если ее нет, будет ошибка. Это логично.
ЭТО - Логично...
А вот КАК узнать, что динамической памяти нет, и не завершить программу с RunTime Error, а выдать простое и понятное сообщение, и при этом, возможно, еще откатиться назад, чтобы удалить ранее созданные объекты (если, например, они создавались для поддержки работоспособности того, который не смог инициализироваться), чтобы корректно сохранить информацию из них куда-нибудь в файл, а не потерять ее (кто знает, сколько времени программа накапливала информацию, может она работала несколько часов, и что? Все будет утеряно?)... Это чья задача? Операционной системы/компилятора, или все-же твоя, как программиста?