Polymorfism ?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
gogonk
незнакомец
Сообщения: 3
Зарегистрирован: 12.06.2008 23:37:20

Polymorfism ?

Сообщение gogonk »

Код: Выделить всё

program Untitled;
uses
   SysUtils;
type
   TItems = record
      id: integer;
      name: string;
   end;

   T1 = class
      procedure add(p: Pointer);
      function getRecord: Pointer; virtual;
   end;

   T2 = class(T1)
      t: TItems;
      function getRecord: Pointer; override;
   end;

procedure T1.add(p: pointer);
var
   f: FILE;
begin
   assignfile(f,'data.txt');
   reset(f);
   write(f, getRecord^);  ??????????????????
   close(f);
end;
function T1.getRecord: pointer;
begin
   result := NIL;
end;
function T2.getRecord: pointer;
begin
   result := @t;
end;
begin
   writeln('Hello');
   readln;
end.

Почему fpc дает ошибка здесь : write(f, getRecord^);
f: FILE не может. Нужно было FILE of ...
Дельфи этот компилирует.
mike
новенький
Сообщения: 55
Зарегистрирован: 23.02.2007 16:25:00

Сообщение mike »

Потому что GetRecord возвращает нетипизированный указатель, следовательно тип данных конструкции GetRecord^ не определен. Функции же wite/writeln умеют выводить только строки и перечисляемые типы (Integer, Boolean и т.п.), исключением является только указатель PChar, который интерпретируется как строка. Все что угодно в нетипизированный файл умеет выводить функция BlockWrite.

Простейшее решение состоит в замене write(f, getRecord^) на BlockWrite(f, getRecord^, SizeOf(TItems)), но тогда открвать файл нужно вызовом Reset(f, 1). Либо наоборот, файл открываем с указанием полного размера используемого блока Reset(f, SizeOf(TItems)), а пишем уже только один такой блок BlockWrite(f, getRecord^, 1).
gogonk
незнакомец
Сообщения: 3
Зарегистрирован: 12.06.2008 23:37:20

Сообщение gogonk »

Т.е. в fpc нет поздное связивание как в Delphi ?
ev
долгожитель
Сообщения: 1797
Зарегистрирован: 27.04.2005 23:19:06
Откуда: Москва

Сообщение ev »

gogonk
учимся юзать теги форума ;)
gogonk
незнакомец
Сообщения: 3
Зарегистрирован: 12.06.2008 23:37:20

Сообщение gogonk »

Аха, это супер.
v-t-l
энтузиаст
Сообщения: 745
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение v-t-l »

А то, что файл открыт Reset вместо Rewrite или Append, - это ничего?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Чтобы FPC вел себя, как Дельфи, нужно в начале программы писать {$mode delphi}{$h+}. Или компилировать с ключом -Sdh.
Михаил Крамер
новенький
Сообщения: 73
Зарегистрирован: 08.02.2008 13:26:40

Сообщение Михаил Крамер »

М-да... Полиморфизм.... А так почему нельзя?

Код: Выделить всё

type
   T1 = class
    public
           procedure write(f:text); virtual; abstract;
    end;
    T2 = class (t1)
    public
          procedure write(f:text); virtual;
    end;
procedure t2.write(f:text);
begin
    write(f, 'Бребедень всякая');
end;


А то, ммм.., как то коряво выглядела прога - что за полиморфизм, если нужно sizeof делать?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Так тоже можно, только:
1) переменную типа файл нужно передавать по ссылке: procedure write(var f:text);
2) Если используем классы, то для перекрытия метода нужно ключевое слово override.

С учетом исправлений получается:

Код: Выделить всё

type
   T1 = class
    public
           procedure write(var f:text); virtual; abstract;
    end;
    T2 = class (t1)
    public
          procedure write(var f:text); override;
    end;

procedure t2.write(var f:text);
begin
    write(f, 'Бребедень всякая');
end;
Михаил Крамер
новенький
Сообщения: 73
Зарегистрирован: 08.02.2008 13:26:40

Сообщение Михаил Крамер »

М-да, синтаксис то я и подзабыл.

Но возвращать адрес поля класса, да ещё и из виртуальной функции - это не ООП, а нечто неописуемое. Можно же всю абстракцию порушить! Да и программу!
Ответить