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

Вниз

Проблема с описанием метода в потомке класса   Найти похожие ветки 

 
lipskiy   (2003-11-01 00:19) [0]

Существует два экземпляра Some1 и Some2 класса TSome.
Каждый экземпляр содержит данные, формат которых я описываю отдельно для каждого экземпляра так:

type

PData1 = ^TData1;
TData1 = record
Caption : string;
Level : integer;
end;

PData2 = ^TData2;
TData1 = record
Position : real;
Level : integer;
end;


Класс TSome имеет событие OnInit. В обработчике этого события для каждого экземпляра класса я должен проинициализировать поле данных Level.

Хочу создать потомок класса - TMySome, куда включить обработчик события OnInit, поскольку для каждого экзепляра код обработчика события одинаков, отличие только в формате данных.

Сейчас обработчики события OnInit для каждого экземпляра класса выглядят так:

procedure TForm1.Some1Init(Sender: TSome);
var Data : PData1;
begin
Data:= Sender.GetData;
Data.Level:= SomeFunction;
end;

procedure TForm1.Some2Init(Sender: TSome);
var Data : PData2;
begin
Data:= Sender.GetData;
Data.Level:= SomeFunction;
end;


Как видно, код обработчиков одинаков, но описатели Data разные, хотя и имеют идентичное поле Level.

Вопрос: можно ли как-то описать в потомке класса TSome (в TMySome) обработчик события OnInit так, чтобы он мог использовать идентичные поля описателей Data при различиях в остальных полях? DataSize у данных каждого экземпляра разный.


 
Ломброзо   (2003-11-01 00:55) [1]

Сделай так: интеджер вынеси первым полем,
type
PInt = ^TInt;
TInt = record
Level: integer;
end;

PData1 = ^TData1;
TData1 = record
Level : integer;
Position : real;
end;

Далее,
PInt(Data)^.Level := SomeFunction;

Попахивает хакерстом, 7-ка наверняка ругаться будет.


 
Ломброзо   (2003-11-01 00:57) [2]

или как-нибудь в рантайм смещение адреса Level отсчитывай.


 
lipskiy   (2003-11-02 20:05) [3]

Все получилось! Спасибо!
D7 не ругается, первый вариант работает.
То есть, насколько я понял, в этом случае происходит обращение к данным, которые объявлены дважды (в потомке класса и в головной программе), но занимают одну общую область памяти. Из головной программы инициализируется DataSize, включающий в себя все поля данных, а из потомка класса DataSize вообще не инициализируется но обращение к полю Level делается, и это поле физически расположено в том же самом месте, что и поле Level, объявленное в головной программе.
Верно я понял физику явления?

А не опасен ли такой метод? А если опасен, то чем?


 
Ломброзо   (2003-11-02 20:34) [4]

В принципе ничем не опасен, если ты вынес поле Integer вперед, тогда смещение адреса относительно начала структуры равно 0. Если же у тебя в структурах винегрет из разных типов данных и ты хочешь проинициализировать вторую или там третью, то это уже опасно из-за разного sizeof этих типов и выравнивания, производимого компилятором. С трудом представляю, где вообще такой прием может понадобиться. В С++ проще, там смещение можно высчитать макросами при компиляции. См. также аттрибут Packed.

Есть еще одно рацпредложение - используй структуры вариантов, будет немного потормознее, но удобнее.
type
TMyRecord = record
a, b, c, d: Variant; // OleVariant
end;


 
lipskiy   (2003-11-03 00:39) [5]

Не, мне надо быстро, у меня дерево большое (Tree).
Меня первый вариант вполне устраивает, тем более что я его понимаю и он не опасен, а с вариантами я не умею обращаться.



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

Форум: "Основная";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.035 c
3-41042
Кодер
2003-10-15 09:55
2003.11.13
Как вставить картинки в MSSQL?


1-41196
Ivolg
2003-11-02 13:12
2003.11.13
Кнопка закрыть


9-40761
Начинающий_программист
2003-05-05 11:47
2003.11.13
Послушайте!


1-41153
2ТЭ10М
2003-11-03 12:06
2003.11.13
Принудительная выгрузка преложения.


14-42094
Думкин
2003-10-23 04:30
2003.11.13
С днем рождения! 23 октября





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский