Форум: "Компоненты";
Текущий архив: 2006.12.31;
Скачать: [xml.tar.bz2];
ВнизКак определить предка? Найти похожие ветки
← →
Lanc (2006-04-20 09:11) [0]Такая ситуация:
Создается класс TUniSeriesTUniSeries=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