Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.06;
Скачать: CL | DM;

Вниз

Как работать со ссылками на классы?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.046 c
9-1101904980
VolanD666
2004-12-01 15:43
2005.03.06
Корявая прорисовка (Direct3D)


14-1108560041
kaZaNoVa
2005-02-16 16:20
2005.03.06
RSA-шифрование


3-1107520454
pashtet
2005-02-04 15:34
2005.03.06
Подскажите процедуру/функцию которая прибавл. месяц к дате.


1-1108304762
Сергей Ю.
2005-02-13 17:26
2005.03.06
Как можно разделить функции одной программы между несколькими?


14-1108389364
Cosinus
2005-02-14 16:56
2005.03.06
Иконки для контактов(изображение телефонов, моб. тел, домов, )...