![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как работать со ссылками на классы?
TUser © (2005-02-17 13:40:00)Есть вот такое
TAncestor = class
...
end;
TAncClass = class of TAncestor;
TDesc = class(TAncestor)
public
property Item[Index: integer]: TAnyType read ... write ...;
end;
Теперь я в другом классе пишу
TWorker = class
private
FRef: TAncClass;
FArray: array of TAncestor;
public
procedure AnyProc;
constructor Create;
end;
...
constructor TWorker.Create;
begin
inherited;
FRef:=TAncClass(TDesc);
end;
procedure TWorker.AnyProc;
begin
with FRef(FArray[i]) do
Items[i]:= ....
end;
При этом в массиве FArray лежат объекты классa TDesc.
Почему на выделенной строке пишет Missing operator or semicolon?Точки с запятыми все
стоят, как надо.
И как правильно работать со ссылками на класс, а именно - как сделать так,
чтобы в методеTWorker.AnyProcнаписатьFRef(...)
- и работать далее так же, как если бы было написаноTDesc( .... Это примерно тоже самое, что в плясах называется шаблонами.
)
icWasya (2005-02-17 16:15:00) [1]по тому коду, который ты привёл достаточно такого
TAncestor = class
...
protected
function ReadAny(index:Integer):TAnyClass;virtual;
procedure WriteAny(index:Integer;Value:TAnyClass);virtual;
public
property Item[Index: integer]: TAnyType read ... write ...;
end;
TAncClass = class of TAncestor;
TDesc = class(TAncestor)
protected
function ReadAny(index:Integer):TAnyClass;override;
procedure WriteAny(index:Integer;Value:TAnyClass);override;
end;
Теперь я в другом классе пишу
TWorker = class
private
FRef: TAncClass;
FArray: array of TAncestor;
public
procedure AnyProc;
constructor Create(ARef:TAncClass);// лучше так
end;
...
constructor TWorker.Create(ARef:TAncClass);
begin
inherited;
FRef:=ARef;
end;
procedure TWorker.AnyProc;
begin
with FArray[i] do
Items[i]:= ....
end;
...
и гдето ещё
FWorker:=TWorker.Create(TDest);
а использовать TAncClass = class of TAncestor имеет смысл в тех случаях, когда у типа TAncestor есть виртуальные классовыеметоды, например конструктор:
TAncestor = class
...
constructor Create(aName:String);virtual;
...
тогда у класса TWorker можно будет дописать такой метод
procedure TWorker.AddAncestor(aName:String);
begin
SetLength(FArray,Length(FArray)+1);
FArray[High(FArray)]:=FRef.Create(aName);// здесь будет вызван конструктор TDest
end;
У (2005-02-17 15:38:00) [2]2TUser © (17.02.05 13:40)
Собственно говоря, когда ты обрабатываешь массив
разнородных объектов, возможны два случая:
1) Во всех них присутствует некоторая общность,
известная на этапе компиляции.
Например, они потомки одного класса, определяющего
виртуальные ф-и, которые они перекрывают.
Или реализуют определённые интерфейсы.
Или обрабатывают определённые сообщения.
Соответственно код пишется в терминах этой общности.
2) Производится последовательная обработка
всех частных случаев.
Третьего не дано.
TUser (2005-02-17 15:28:00) [3]Увы.
У (2005-02-17 15:24:00) [4]2Чапаев © (17.02.05 15:18) [8]
Так не сработает:
FArray[I] is FRef
Надо
FArray[I].InheritsFrom(FRef)
И вообще, это тупиковый путь.
Чапаев (2005-02-17 15:18:00) [5]> FRef:=TAncClass(TDesc);
Просто FRef:=TDesc;
> with FRef(FArray[i]) do
> Items[i]:= ....
Ну не знаю даже... Неправильно это... Items у тебя ведь в классе-наследнике определено... Я бы сделал что-то вроде:
if FRef=TDesc then
if FArray[I] is FRef then
with FArray[I] as FRef do
Items[I]:=...;
У (2005-02-17 14:47:00) [6]>Пардон, подчеркнутов д.б. вот эта строка
Ну тогда я тебе ответил - пункт 3)
TUser (2005-02-17 14:07:00) [7]Пардон, подчеркнутов д.б. вот эта строка
> with FRef( FArray[i]) do
Компилятор ставит курсор на жирную букву F и пишет Missung operator ...
А 'ссылка на класс' - это я так перевел Class Refference. И не только я - в русском издании Конопки терминология такая же.
У (2005-02-17 14:06:00) [8]2Alexander Panov ©
FRef: TAncClass; - это не ссылка на класс, это объект типа
TAncClass(читай ссылка на объект класса).
ИМХО, обычная ссылка на класс, сиречь указатель на VMT.
У (2005-02-17 14:03:00) [9]>TUser ©
1) подчёркнутой строки я не вижу, ничего по сему поводу
сказать не могу
2)чтобы создавать экземпляр по классовой ссылке,
у базового класса (TAncestor) должен быть виртуальный конструктор.
3)"написать FRef(...)
- и работать далее так же, как если бы было написано TDesc( ..."
Так не получится. Чтобы привести объект к некоторому классу,
на этапе компиляции нужно знать, что это за класс, какие у него члены и тп.
Всё, что ты можешь сделать - привести к TAncestor
Alexander Panov (2005-02-17 13:58:00) [10]Fay © (17.02.05 13:56) [2]
Если уж на то пошло, то TAncClass - это как минимум класс 8)
Угу, TAncClass - это класс-)
а вот объект класса - это нечто другое-)
в дополнение к Alexander Panov © (17.02.05 13:44) [1]
FRef: TAncClass; - это не ссылка на класс, это объект типа TAncClass(читай ссылка на объект класса).
Fay (2005-02-17 13:56:00) [11]2 Alexander Panov © (17.02.05 13:44) [1]
Если уж на то пошло, то TAncClass - это как минимум класс 8)
Alexander Panov (2005-02-17 13:44:00) [12]FRef: TAncClass; - это не ссылка на класс, это объект типа TAncClass.