Вверх ↑
Этот топик читают: Гость
Ответов: 2329
Рейтинг: 681
#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
Ответов: 1841
Рейтинг: 369
#2: 2015-12-03 12:40:13 ЛС | профиль | цитата
Смотрите в сторону RTTI (идентификация типа во время исполнения).

карма: 1
1
Голосовали:sla8a
Ответов: 4646
Рейтинг: 759
#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 правка | ЛС | профиль | цитата


Редактировалось 8 раз(а), последний 2025-02-28 09:50:50
карма: 0

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

0
Ответов: 4646
Рейтинг: 759
#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
Ответов: 2329
Рейтинг: 681
#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
Ответов: 2329
Рейтинг: 681
#10: 2015-12-03 16:58:20 ЛС | профиль | цитата
Подскажите в чем здесь ошибка:
code_36601.txt
карма: 11

0
файлы: 1code_36601.txt [709B] [637]
Ответов: 4646
Рейтинг: 759
#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
Ответов: 2329
Рейтинг: 681
#13: 2015-12-03 18:35:05 ЛС | профиль | цитата
CriDos, Netspirit, спасибо что подтолкнули, дальше попробую своим ходом.
карма: 11

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