Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
ВнизКак работать со ссылками на классы? Найти похожие ветки
← →
TUser © (2005-02-17 13:40) [0]Есть вот такое
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( ...
. Это примерно тоже самое, что в плясах называется шаблонами.
)
← →
Alexander Panov © (2005-02-17 13:44) [1]FRef: TAncClass; - это не ссылка на класс, это объект типа TAncClass.
← →
Fay © (2005-02-17 13:56) [2]2 Alexander Panov © (17.02.05 13:44) [1]
Если уж на то пошло, то TAncClass - это как минимум класс 8)
← →
Alexander Panov © (2005-02-17 13:58) [3]Fay © (17.02.05 13:56) [2]
Если уж на то пошло, то TAncClass - это как минимум класс 8)
Угу, TAncClass - это класс-)
а вот объект класса - это нечто другое-)
в дополнение к Alexander Panov © (17.02.05 13:44) [1]
FRef: TAncClass; - это не ссылка на класс, это объект типа TAncClass(читай ссылка на объект класса).
← →
У (2005-02-17 14:03) [4]>TUser ©
1) подчёркнутой строки я не вижу, ничего по сему поводу
сказать не могу
2)чтобы создавать экземпляр по классовой ссылке,
у базового класса (TAncestor) должен быть виртуальный конструктор.
3)"написать FRef(...)
- и работать далее так же, как если бы было написано TDesc( ..."
Так не получится. Чтобы привести объект к некоторому классу,
на этапе компиляции нужно знать, что это за класс, какие у него члены и тп.
Всё, что ты можешь сделать - привести к TAncestor
← →
У (2005-02-17 14:06) [5]2Alexander Panov ©
FRef: TAncClass; - это не ссылка на класс, это объект типа
TAncClass(читай ссылка на объект класса).
ИМХО, обычная ссылка на класс, сиречь указатель на VMT.
← →
TUser © (2005-02-17 14:07) [6]Пардон, подчеркнутов д.б. вот эта строка
> with FRef(FArray[i]) do
Компилятор ставит курсор на жирную букву F и пишет Missung operator ...
А "ссылка на класс" - это я так перевел Class Refference. И не только я - в русском издании Конопки терминология такая же.
← →
У (2005-02-17 14:47) [7]>Пардон, подчеркнутов д.б. вот эта строка
Ну тогда я тебе ответил - пункт 3)
← →
Чапаев © (2005-02-17 15:18) [8]> 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 15:24) [9]2Чапаев © (17.02.05 15:18) [8]
Так не сработает:
FArray[I] is FRef
Надо
FArray[I].InheritsFrom(FRef)
И вообще, это тупиковый путь.
← →
TUser © (2005-02-17 15:28) [10]Увы.
← →
У (2005-02-17 15:38) [11]2TUser © (17.02.05 13:40)
Собственно говоря, когда ты обрабатываешь массив
разнородных объектов, возможны два случая:
1) Во всех них присутствует некоторая общность,
известная на этапе компиляции.
Например, они потомки одного класса, определяющего
виртуальные ф-и, которые они перекрывают.
Или реализуют определённые интерфейсы.
Или обрабатывают определённые сообщения.
Соответственно код пишется в терминах этой общности.
2) Производится последовательная обработка
всех частных случаев.
Третьего не дано.
← →
icWasya © (2005-02-17 16:15) [12]по тому коду, который ты привёл достаточно такого
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;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.037 c