Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 2006.12.31;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.045 c
2-1165772153
lobach
2006-12-10 20:35
2006.12.31
Как отследить запуск приложения?


15-1164994284
Cyrax
2006-12-01 20:31
2006.12.31
Оптимальный стиль программирования


2-1165686682
ezorcist
2006-12-09 20:51
2006.12.31
Уничтожить TClientSocket после disconnect-а.


1-1163401076
DelphiLexx
2006-11-13 09:57
2006.12.31
Отключить стиль XP для контрола


15-1165577292
ocean
2006-12-08 14:28
2006.12.31
Запись звука с линейного выхода





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский