Вверх ↑
Этот топик читают: Гость
Ответов: 2202
Рейтинг: 675
#1: 2015-12-03 12:10:23 ЛС | профиль | цитата
Заранее извиняюсь за постановку вопроса, но так как самоучка и терминами владею плохо, то изложу по простому.
Что Pointer указатель (адрес) памяти, а PList список этих указателей (адресов) понятно.
Есть два типа указателя
#pas
myList: PList;

TFirst = record
name: string;
age: integer;
end;
PFirst = ^TFirst;

TSecond = record
name: TPoint;
age: TRect;
end;
PSecond = ^TSecond;
Вопрос: Можно както определить тип указателя :?:
#pas
if myList.Items[3] = PSecond then // ???

карма: 11

0
vip
#1.1контекстная реклама от партнеров
Ответов: 1841
Рейтинг: 369
#2: 2015-12-03 12:40:13 ЛС | профиль | цитата
Смотрите в сторону RTTI (идентификация типа во время исполнения).

карма: 1
1
Голосовали:sla8a
Ответов: 4622
Рейтинг: 746
#3: 2015-12-03 13:00:37 ЛС | профиль | цитата
Думаю, есть такие варианты:
- программист сам знает, какой тип данных он помещает в список, если в списке только один тип
- если типов несколько, но они реализованы подобной структурой, то в TSecond можно добавить первым поле, указывающее на назначение структуры
- или можно вместо TSecond = record объвить TSecond = class, и тогда в коде можно использовать такую конструкцию if TObject(myList.Items[3]) is TSecond then... Но естественно, кроме классов в TList ничего не должно быть.
карма: 26

1
Голосовали:sla8a
Гость
Ответов: 17029
Рейтинг: 0
#4: 2015-12-03 14:14:51 правка | ЛС | профиль | цитата


Редактировалось 5 раз(а), последний 2021-05-21 09:30:08
карма: 0

0
Ответов: 2202
Рейтинг: 675
#5: 2015-12-03 14:17:12 ЛС | профиль | цитата
Выше мое, вылетел.
карма: 11

0
Ответов: 4622
Рейтинг: 746
#6: 2015-12-03 14:24:36 ЛС | профиль | цитата
Либо
if PFirst(myList.Items[3])^.type = 1 then
либо
if PByte(myList.Items[3])^ = 1 then

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

1
Голосовали:sla8a
Ответов: 1841
Рейтинг: 369
#7: 2015-12-03 16:22:52 ЛС | профиль | цитата
sla8a писал(а):
Не понятны мне эти class-ы Сколько статей перечитал, как в интернете так и в книгах, но до сих пор не понимаю как с ними работать.

RTTI работает только с классами (в Delphi), информацию о структурах (рекордах) компилятор не сохраняет (вроде):
wiki писал(а):
Компилятор Delphi сохраняет в исполняемом файле программы информацию обо всех классах, используемых в ней. При создании любого объекта в памяти перед ним (по отрицательным смещениям) располагается заголовок, в котором есть в том числе ссылка на структуру-описатель класса этого объекта. Встроенные в язык функции работают с этой информацией прозрачно для программиста. Оператор is позволяет проверить, является ли объект или тип наследником определённого типа, а оператор as используется для приведения объектов или интерфейсов от одного типа к другому, являясь аналогом dynamic_cast в C++.

Заголовки объектов — также неявно — используются для автоматического управления памятью.

Так что, либо самому в поле структуры (рекорда, или как там их в Delphi) хранить тип объекта, либо переходить на классы.
------------ Дoбавленo в 16.22:
sla8a писал(а):
Пока понятных для меня примеров не нашел. Может есть наглядный пример или ссылка?

Как-то так
http://pastebin.com/yhrrsH2N - не смог на форуме корректно вставить код
карма: 1
1
Голосовали:sla8a
Ответов: 2202
Рейтинг: 675
#8: 2015-12-03 16:32:58 ЛС | профиль | цитата
CriDos, обновите схему, а то вижу что на форуме весь код в InlineCode, а вставляю в HiAsm часть кода пропадает.
карма: 11

0
Ответов: 1841
Рейтинг: 369
#9: 2015-12-03 16:38:23 ЛС | профиль | цитата
sla8a писал(а):
часть кода пропадает

Ага, минут 5 мучился, пытался вставить, нифига.
Перезалил на пастбин
------------ Дoбавленo в 16.38:
Наследоваться от TObject не обязательно.
Можно и так
...
TTest = class
...
Это я экспериментировал, забыл убрать.
карма: 1
1
Голосовали:sla8a
Ответов: 2202
Рейтинг: 675
#10: 2015-12-03 16:58:20 ЛС | профиль | цитата
Подскажите в чем здесь ошибка:
code_36601.txt
карма: 11

0
файлы: 1code_36601.txt [709B] [506]
Ответов: 4622
Рейтинг: 746
#11: 2015-12-03 17:05:25 ЛС | профиль | цитата
С классами такое приведение типов не сработает как с Record. Нет, не так понял код
Пробуй
if TObject(myList.Items[1]) is TFirst then
_hi_OnEvent(onEvent, TFirst(myList.Items[1]).Name);


Точнее приведение работает, главное перед тем как обращаться к классу, нужно проверять его тип. Хотя в твоем случае да, проблема в неправильном создании списка.
карма: 26

1
Голосовали:sla8a
Ответов: 1841
Рейтинг: 369
#12: 2015-12-03 17:47:03 ЛС | профиль | цитата
Не знаю чего там у вас не приводится, всё должно приводиться
Просто список неправильно создавался.
#pas
procedure THiAsmClass.doWork;
var
Tf: TFirst;
Ts: TSecond;
myList: PList;
begin
myList := NewList;
Tf := TFirst.Create;
Tf.name := 'BlaBlaBla';
Ts := TSecond.Create;
Ts.age := 333;
myList.Add(Ts);
myList.Add(Tf);
_hi_OnEvent(onEvent, myList.Count);
_hi_OnEvent(onEvent, TFirst(myList.Items[1]).Name);
// myList.Destroy;
end;
end.
------------ Дoбавленo в 17.47:
Более того, если смещения и типы необходимых полей классов совпадают, можно без опасений обращаться к таким полям после приведения (кастования?).
unit HiAsmUnit;

interface

uses Kol,Share,Debug;

type
THiAsmClass = class(TDebug)
private

public
onEvent:THI_Event;
procedure doWork(var dt:TData; idx:word);

end;

TFirst = class
public
first: integer;
foo: string;
goo: string;

end;

TSecond = class
public
second: integer;
bar: string;

end;

implementation

procedure THiAsmClass.doWork;
var
Tf: TFirst;
Ts: TSecond;
myList: PList;
begin
myList := NewList;
Tf := TFirst.Create;
Tf.foo := 'foo';
Ts := TSecond.Create;
Ts.bar := 'bar';
myList.Add(Ts);
myList.Add(Tf);
_hi_OnEvent(onEvent, TFirst(myList.Items[0]).foo);
_hi_OnEvent(onEvent, TFirst(myList.Items[1]).foo);
// myList.Destroy;
end;
end.
карма: 1
1
Голосовали:sla8a
Ответов: 2202
Рейтинг: 675
#13: 2015-12-03 18:35:05 ЛС | профиль | цитата
CriDos, Netspirit, спасибо что подтолкнули, дальше попробую своим ходом.
карма: 11

0
13
Сообщение
...
Прикрепленные файлы
(файлы не залиты)