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

Вниз

Как определить предка?   Найти похожие ветки 

 
Lanc   (2006-04-20 09:11) [0]

Такая ситуация:

Создается класс TUniSeries

 TUniSeries=class
  public
   Ser:TChartSeries;
   CatNum:byte;
 End;


Создается несколько объектов этого типа. Поле Ser добавляется к TChart, рисуются графики, все отображается нормально и вроде проблем никаких нет.
Но в определенный момент я просматриваю сериесы, которые ассоциированны с определенным TChart.

Var nls:TChartSeries;

For i:=0 to Ch.SeriesCount-1 do
Begin
 Nls:=TChartSeries(ch.SeriesList[i]);
//и в этом месте мне надо получить доступ к объекту типа TUniSeries, который является предком соответствующего сериеса (конкретно мне нужно просмотреть поле CatNum). Возможно ли это сделать?
End;


Может кто-то подскажет как получить предка? Или я вообще неправильно ситуацию понимаю и это невозможно?
Заранее благодарен.


 
Юрий Зотов ©   (2006-04-20 10:12) [1]

> Lanc   (20.04.06 09:11)

Тут терминологическая ошибка - речь идет не о предке поля, а о его владельце. Есть ссылка на объект (класса TChartSeries), которая, возможно, является полем другого объекта (класса TUniSeries). Надо проверить, действительно ли это так и если да, то определить этот второй объект.

Если известно смещение поля относительно "начала" его владельца (а оно в данном случае известно, поскольку объект TUniSeries мы спроектировали сами), то сделать это можно - правда, полухакерским способом.

Сначала предположим, что поле действительно принадлежит нашему объекту и получим адрес этого объекта (он равен адресу своего первого поля минус размер ссылки на класс), а затем проверим, действительно ли по полученному адресу расположен именно наш объект, а не что-то другое.

var
 Obj: TObject;
 UniSeries: TUniSeries absolute Obj;

Obj := TObject(Integer(Nls) - SizeOf(TClass));
if not (Obj is TUniSeries) then
 raise Exception.Create("Ссылка на объект TChartSeries не является полем объекта TUniSeries");
... // Здесь можем работать с объектом UniSeries.


PS
Но вообще, если приходится прибегать к подобным трюкам, то сам подход выглядит несколько подозрительно и ОЧЕНЬ похож на кривое проектирование. Например, стоит лишь модифицировать класс TUniSeries, добавив перед полем Ser что-то еще - и код тут же становится неверным. В то время, как при нормальном следовании канонам ООП такого быть не должно.


 
Lanc   (2006-04-20 10:27) [2]


> Но вообще, если приходится прибегать к подобным трюкам,
> то сам подход выглядит несколько подозрительно и ОЧЕНЬ похож
> на кривое проектирование.

Может вы тогда подскажете, как надо было спроектировать,чтобы было не криво? Ну в смысле, направите в нужно сторону.
Цель-то такова, что необходимо иметь набор TChartSeries, при этом они должны иметь ряд дополнительных параметров. Изначально я собирался сделать это модифицировав TChartSeries (т.е. свой класс создать на его основе), но ничего хорошего из этого не вышло.


 
Юрий Зотов ©   (2006-04-20 11:00) [3]

> Lanc   (20.04.06 10:27) [2]

> Изначально я собирался сделать это модифицировав TChartSeries (т.е.
> свой класс создать на его основе), но ничего хорошего из этого не вышло.

Вот это решение и было правильным. Что конкретно не вышло?


 
Lanc   (2006-04-20 11:37) [4]


> Что конкретно не вышло?

При создании такого ChartSeries (допустим, класс назвали TUniChartSeries), необходимо указать какой он именно. Т.е. TLineSeries, TPointSeries и т.п.
Если он создается именно как TChartSeries  (через inherited create), то это не подходит.
Может я опять же чего-то недопонял.
Я делал так:
определен конструктор:
TUniChartSeries=class(TChartSeries)
puclic
 CatNum:byte;
 Constructor create(AOwner:TComponent;ct:byte);
end;
...
Constructor TUniChartSeries.create(AOwner:TComponent;ct:byte);
begin
inherited create(AOwner);
CatNum:=ct;
end;


Но в этом случае он будет именно ChartSeries, а мне надо, чтобы при создании я мог указать какой он именно. LineSeries или какой другой.
Если Вы можете подсказать как это сделать, был бы очень благодарен :)


 
evvcom ©   (2006-04-25 13:49) [5]

Дело в том, что TLineSeries, TPointSeries и т.п. уже являются наследниками TChartSeries и уже не могут быть наследниками TUniChartSeries, в которого ты пытаешься добавить CatNum:byte; чтобы это поле присутствовало в твоих Series. Варианты:
1. Сделать наследников от каждого из нужных тебе TLineSeries, TPointSeries, ..., добавив в каждый из них поле CatNum.
2. Сделать наследника TUniChartSeries от TChartSeries, а потом наследников от TUniChartSeries, реализующих возможности TLineSeries, TPointSeries.
3. Найти свойство в общем предке, в котором можно было бы хранить пользовательские данные, такое как TComponent.Tag.

Я всегда стараюсь пойти по 3-му пути, и пока мне это удавалось. Как ни странно, но TChartSeries является прямым наследником от TComponent и поэтому свойство Tag доступно в любом из наследников. Его и используй в качестве CatNum



Страницы: 1 вся ветка

Текущий архив: 2006.12.31;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.048 c
2-1165498131
Danger-Lifter
2006-12-07 16:28
2006.12.31
Проблема с потоками


15-1165601755
Pok
2006-12-08 21:15
2006.12.31
Как написать на Delphi?


1-1163431096
DVM
2006-11-13 18:18
2006.12.31
Изменение размеров формы до ее показа. Странность.


15-1165594151
Kerk
2006-12-08 19:09
2006.12.31
Какнить вообще можно бороться с такими уродами?


3-1160737584
Antoxa2005
2006-10-13 15:06
2006.12.31
Подскажите, а как сменить пароль пользователя SYSDBA программно?