Как создать метакласс всех предков?

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

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

Как создать метакласс всех предков?

Сообщение Danila » 27.10.2017 12:43:17

Возможно ли создать метакласс всех предков? Если да, то как?
Например:
У меня есть класс Tool, а его потомки Fig и Zoo, а у Fig и Zoo тоже есть потомки. Как создать метакласс для Tool, чтобы можно было достучатся до потомков Fig и Zoo?
Danila
незнакомец
 
Сообщения: 1
Зарегистрирован: 27.10.2017 12:37:11

Re: Как создать метакласс всех предков?

Сообщение Cheb » 28.10.2017 09:22:17

Код: Выделить всё
type
   CTool = class of TTool;
var
  t: TTool;
  c: CTool;
...
  c:= TZoo;
...
  t:= TTool(c.Create()); //уже забыл, зачем приведение типа нужно, но оно нужно.


P.S. Переменной предкового типа можно присваивать любых потомков этого типа - естественно, знать она будет только о тех методах, что есть у этого предкового типа. Для того механизм виртуальных методов и нужен. Чтобы код мог работать с потомками, как с чёрными ящиками, не подозревая о том, что это уже не предок.

P.P.S. Если нужно копать глубже, возможны извращения типа
Код: Выделить всё
  if t is TZoo then with TZoo(t) do begin
    ZooDo();
  end;

или, но это уже бомбанёт исключением, если t - не TZoo, а, например, TCarFactory:
Код: Выделить всё
  (t as TZoo).ZooDo();
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 592
Зарегистрирован: 06.06.2005 15:54:34

Re: Как создать метакласс всех предков?

Сообщение olegy123 » 28.10.2017 10:59:57

Код: Выделить всё
TTool = class if(..)
TFig=Class of (TTool);
TZoo=Class of (TFig);

var
  tool_obj:TTool;
  fig_obj:TFig;
  zoo_obj:TZoo;
  dymmu_obj:TObject;
  PTool:^TTool;
  pointer_obj:TPointer;

tool_obj:=TTool(zoo_obj);
или
tool_obj:=zoo_obj as TTool;
также можно указать в обратном
zoo_obj:=TZoo(tool_obj);

dymmu_obj:=TObject(zoo_obj)
tool_obj:=TTool(dymmu_obj);

pointer_obj:=@zoo_obj;
tool_obj:=PTool(pointer_obj)^;

tool_obj, fig_obj, zoo_obj - это указатели на участок памяти в котором располагаются данные объекта. Тем самым компилятор понимает что применять нужно с данным объектом. Принудительно приводим одно к другому, даже через pointer, Компилятор не возмущается, считая что мы понимаем что делаем.
olegy123
энтузиаст
 
Сообщения: 757
Зарегистрирован: 25.02.2016 12:10:20

Re: Как создать метакласс всех предков?

Сообщение runewalsh » 28.10.2017 15:49:06

Приведение не нужно, а вот что нужно — отметить конструктор предка как virtual и в потомках его override'ить, иначе для class of T статически вызовется конструктор T вместо правильного. (Собственно, в этом случае class of — встроенный в язык шаблон «фабричный метод», который по-другому так и называется — «виртуальный конструктор»).
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 324
Зарегистрирован: 27.04.2010 00:15:25


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru