Обращение к типам по имению

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
UUU
Сообщения: 310
Зарегистрирован: 17 фев 2004, 09:27
Откуда: Иваново
Контактная информация:

Попробую объяснить на пальцах:

Есть переменные разной структуры (структура почти разная)
var
DSM : TDSM;
DtSM : TDtSM;

в теле:

DSM:=PDSM(Date)^;

Но иногда надо делать и

DtSM:=PDtSM(Date)^;

а дальше работаем уже с нужной переменной. Используются только одинаково названные поля любой из структур.

Вопрос такой - можно ли сделать, что-то наподобие:

var
Dt: pointer;

Dt:=что-требуется('PDSM')(Date)^;

Dt.Pole1;
Dt.Pole2.Pole1;

и т.д.
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Нет. Так делать нельзя.
Если типы "почти разные" то может лучше использовать case в оописании типа?
Тогда получится один тип, который предусматривает обращение к одной и той же физической области памяти, но используя разную логическую структуру.

Другое решение - объявить две переменных с этими "почти разными типами", но так, чтобы вторая занимала в памяти то же самое место что и первая. Это желается с помошью директивы Absolute при объявлении переменных.

-----------------
См. справку по применению case в описании типов данных и переменных, а также по ключевому слову absolute.


PS
Вообще, Паскаль - пожалуй, самый гибкий язык в отношении высокоуровневого представления структур данных.
UUU
Сообщения: 310
Зарегистрирован: 17 фев 2004, 09:27
Откуда: Иваново
Контактная информация:

Спасибо.
Абсолют не подходит, т.к. структуры разные внутри.
Пробую с кейс:

type
TRSM = record
case CommandId: Cardinal of
cmDS: (
RSM:TDSM;
);

cmDtS: (
RSM:TDtSM;
);
end;

Ругается на второе RSM:TDtSM;

А так действительно было бы прекрасно: объявил переменную этого типа, поставил нужный CommandId и дальше везде обращайся одинаково...

Может я туплю?
Аватара пользователя
Игорь Акопян
Сообщения: 1440
Зарегистрирован: 13 окт 2004, 17:11
Откуда: СПБ
Контактная информация:

а это никак не реализовать с помощью объектной технологии? Типа базовый класс, потомок с бОльшим количеством свойств... Обращение к свойствам через виртуальные методы...
Изображение
UUU
Сообщения: 310
Зарегистрирован: 17 фев 2004, 09:27
Откуда: Иваново
Контактная информация:

В результате по сути так и сделал
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Ругается на второе RSM:TDtSM;
В разных кейсах нельзя использовать одинаковые имена полей.
А так действительно было бы прекрасно: объявил переменную этого типа, поставил нужный CommandId и дальше везде обращайся одинаково...
Не-е-е-ет. Логика другая (Это ж обрабатывается КОМПИЛЯТОРОМ, которому наплевать на значение CommandId!!!)
CommandID - это поле для Ваших алгоритмов. Они в зависимости от CommandID должны обрабатывать использовать одно поле или другое, причем физически в памяти они пересекаются!

T.е. в одном месте:

X.CommandID:=cmDS;
X.RSM1:=<value of TDSM>;

А в другом:
Case X.CommandID of .... и т.д.

Если без проверки дернуть X.RSM2, то там будет лажа. Или напротив, если сделать X.RSM2:=<value of TDtSM>;
то будет испорчено значение X.RSM1.


Наиболее яркий методический пример использования case это побайтный и пословный доступ к двойному слову

Код: Выделить всё

type
  TDWord = record
     case byte of
     0: (D: DWORD;);
     1: (W_Lo,W_Hi: Word;);
     2: (B_LoLo,B_LoHi,B_HiLo,B_HiHi:Byte;);
  end;
var
  X:TDword;
Теперь пишем
X.D:=321321321;

Теперь X.W_Lo будет равен 63849, т.е. младшему слову этого двойного слова.

Я просто не понял, насколько различаются TDSM и TDtSM.
Если Вы разрабатываете какой-то протокол, то как раз кейсы - это то что надо. Очень удобно для разбора: Тип команды, а за ним лежат данные, которые должны быть проинтерпретированы в соответствии с типом команды.
Правда пакетики получатся фиксированного размера (равного размеру наидлиннейшего кейса). Так как переменная быдет съедать столько памяти, чтобы любой кейс поместился...
UUU
Сообщения: 310
Зарегистрирован: 17 фев 2004, 09:27
Откуда: Иваново
Контактная информация:

Эту задачу, что называется, решил в лоб: в коде кейс и необходимое присваивание.
Но появилась другая задача:

Есть тип. И есть пары строки(массив) "имя-значение".
Т.е. надо сделать присваивание (обращение)
тип.имя:=значение.

В перле для таких конструкций есть например eval. Как быть в дельфях?

Причем в какой-то момент может получиться, что у "тип"а нет такого свойства, как "имя". Но это можно и try except отловить...
Ответить