Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.09.15;
Скачать: CL | DM;

Вниз

Работа с указателями   Найти похожие ветки 

 
aka   (2012-12-28 11:35) [0]

Привет, чтобы лучше донести суть вопроса набросал примерчик


program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils;

type
 PA = ^TA;
 TA = record
   recType: string[20];
   field_1: Integer;
   field_2: Integer;
 end;

 PB = ^TB;
 TB = record
   recType: string[20];
   field_3: Integer;
   field_4: Integer;
   name: String[30];
 end;

 PC = ^TC;
 TC = record
   recType: string[20];
   field_5: Integer;
 end;

var
 PtrData: array of Pointer;
 PtrCount: Integer;

 A: PA;
 B: PB;
 C: PC;

 i: Integer;
begin
 PtrCount := 3;
 SetLength(PtrData, PtrCount);

 New(A); //index in PtrData array = 0
 A.recType := "AType";
 A.field_1 := 1;
 A.field_2 := 2;
 PtrData[0] := A;

 New(B); //index in PtrData array = 1
 B.recType := "BType";
 B.field_3 := 1;
 B.field_4 := 2;
 B.name := "ivan";
 PtrData[1] := B;

 New(C); //index in PtrData array = 2
 C.recType := "CType";
 C.field_5 := 1;
 PtrData[2] := C;

 writeln(PA(PtrData[0])^.recType); //out = AType
 writeln(PB(PtrData[1])^.recType); //out = BType
 writeln(PC(PtrData[2])^.recType); //out = CType

 for i := 0 to Length(PtrData) - 1 do
   writeln(i," - ",PA(PtrData[i])^.recType);

 for i := 0 to Length(PtrData) - 1 do
   Dispose(PtrData[i]);

 readln;
end.



Теперь, если мне нужно вывести значения, я могу поступить так:

 writeln(PA(PtrData[0])^.recType); //out = AType
 writeln(PB(PtrData[1])^.recType); //out = BType
 writeln(PC(PtrData[2])^.recType); //out = CType


Здесь мы явно "показываем" тип PA или PB или PC перед PtrData[I], потому что знаем что там "лежит". Вопрос: как быть если мы не знаем что там, но нам нужно узнать какой там находится тип записи (у каждой и трех структур {A,B,C} имеется общее поле recType).

Можно и так, но бутет ли так корректно, применил один из типов, хотя там может быть и другой:

for i := 0 to Length(PtrData) - 1 do
   writeln(i," - ",PA(PtrData[i])^.recType);


 
Сергей М. ©   (2012-12-28 11:44) [1]


> бутет ли так корректно


Не будет.

Собственно а к чему этот велосипед, если он давно уже изобретен, называется RTTI (таблица информации о типах времени выполнения) и сплошь и рядом используется в дельфийских классах и объектах


 
aka   (2012-12-28 11:50) [2]


> Сергей М. ©   (28.12.12 11:44) [1]

Что не будет - догадывался.
RTTI - за это ничего не знаю, почитаю.


 
aka   (2012-12-28 11:51) [3]


> используется в дельфийских классах и объектах

Ну так нужны же именно записи.


 
aka   (2012-12-28 12:04) [4]

А может пойдет?

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

 for i := 0 to Length(PtrData) - 1 do
 begin
   if(PA(PtrData[i])^.recType = "BType") then
     writeln(PA(PtrData[i])^.field_2);

   if(PA(PtrData[i])^.recType = "BType") then
     writeln(PB(PtrData[i])^.name);

   if(PA(PtrData[i])^.recType = "CType") then
     writeln(PC(PtrData[i])^.field_5);
 end;



 
aka   (2012-12-28 12:06) [5]

пардон.


 for i := 0 to Length(PtrData) - 1 do
 begin
   if(PA(PtrData[i])^.recType = "AType") then
     writeln(PA(PtrData[i])^.field_2);

   if(PA(PtrData[i])^.recType = "BType") then
     writeln(PB(PtrData[i])^.name);

   if(PA(PtrData[i])^.recType = "CType") then
     writeln(PC(PtrData[i])^.field_5);
 end;


 
Сергей М. ©   (2012-12-28 12:07) [6]


> нужны же именно записи


Дельфийские классы и объекты и есть ничто иное как записи.


 
Сергей М. ©   (2012-12-28 12:11) [7]


> А может пойдет?
>


Ну в качестве самодельного велосипеда вполне подойдет.

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


 
aka   (2012-12-28 12:15) [8]


> Только непонятно зачем в поле recType держать именно строку,
>  в то время как достаточно одного байта.

просто для примера.


 
aka   (2012-12-28 12:29) [9]


> Ну в качестве самодельного велосипеда вполне подойдет.


ну тогда для красоты и стройности введем дополнительную запись TAccess )))


program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils;

type
 PAccess = ^ TAccess;
 TAccess = record
   recType: String[20];
 end;

 PA = ^TA;
 TA = record
   recType: string[20];
   field_1: Integer;
   field_2: Integer;
 end;

 PB = ^TB;
 TB = record
   recType: string[20];
   field_3: Integer;
   field_4: Integer;
   name: String[30];
 end;

 PC = ^TC;
 TC = record
   recType: string[20];
   field_5: Integer;
 end;

var
 PtrData: array of Pointer;
 PtrCount: Integer;

 A: PA;
 B: PB;
 C: PC;

 i: Integer;
begin
 PtrCount := 3;
 SetLength(PtrData, PtrCount);

 New(A); //index in PtrData array = 0
 A.recType := "AType";
 A.field_1 := 1;
 A.field_2 := 45;
 PtrData[0] := A;

 New(B); //index in PtrData array = 1
 B.recType := "BType";
 B.field_3 := 1;
 B.field_4 := 20;
 B.name := "Ivan Ivanovich";
 PtrData[1] := B;

 New(C); //index in PtrData array = 2
 C.recType := "CType";
 C.field_5 := 909045;
 PtrData[2] := C;

 for i := 0 to Length(PtrData) - 1 do
 begin
   if(PAccess(PtrData[i])^.recType = "AType") then
     writeln(PA(PtrData[i])^.field_2);

   if(PAccess(PtrData[i])^.recType = "BType") then
     writeln(PB(PtrData[i])^.name);

   if(PAccess(PtrData[i])^.recType = "CType") then
     writeln(PC(PtrData[i])^.field_5);
 end;

 for i := 0 to Length(PtrData) - 1 do
   Dispose(PtrData[i]);

 readln;
end.



 
Сергей М. ©   (2012-12-28 12:39) [10]

TAccess - лишняя табуретка, конструкция твоя и без нее достаточно высокая и хлипкая)


 
aka   (2012-12-28 12:43) [11]


> TAccess - лишняя табуретка, конструкция твоя и без нее достаточно
> высокая и хлипкая)


Ну не знаю, а мне нравится...


 
Сергей М. ©   (2012-12-28 12:44) [12]

Ну нравится и нравится)
На вкус и цвет, как говорится, товарищей нет)


 
aka   (2012-12-28 12:52) [13]


>  Сергей М. ©   (28.12.12 12:39) [10]

Что высокая - согласен. Воспользуюсь RTTI.
Ну а в чем же хлипкость?


 
Сергей М. ©   (2012-12-28 13:13) [14]


> в чем же хлипкость?


чем выше конструкция - тем она ненадежнее


 
aka   (2012-12-28 16:18) [15]

А как правильно описать свойства в  классах?

raised exception class EPropertyError with message "Property ObjType does not exist"


program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils, TypInfo;

type
 TCustomObject = class(TObject)
 private
   FObjType: String;
 public
   property ObjType:String read FObjType write FObjType;
 end;
 
 A = class(TCustomObject)
 public
   property ObjType;
 end;

 B = class(TCustomObject)
 public
   property ObjType;
 end;

 C = class(TCustomObject)
 public
   property ObjType;
 end;

var
 PtrObjArray: array of Pointer;
 i,ObjCount: Integer;

 AObj: A;
 BObj: B;
 CObj: C;

 ObjType: String;
 
begin
 SetLength(PtrObjArray,3);

 AObj := A.Create;
 AObj.ObjType := "AClass";
 PtrObjArray[0] := AObj;

 BObj := B.Create;
 BObj.ObjType := "BClass";
 PtrObjArray[1] := AObj;

 CObj := C.Create;
 CObj.ObjType := "CClass";
 PtrObjArray[2] := AObj;

 for i := 0 to Length(PtrObjArray) - 1 do
 begin
   ObjType := GetStrProp(TCustomObject(PtrObjArray[i]), "ObjType");

   if(ObjType = "AClass") then
   begin
   end;

   if(ObjType = "BClass") then
   begin
   end;

   if(ObjType = "CClass") then
   begin
   end;
 end;

 readln;
end.


 
aka   (2012-12-28 16:22) [16]

оп ошибка
PtrObjArray[1] := BObj;
PtrObjArray[2] := CObj;


 
Сергей М. ©   (2012-12-28 16:28) [17]

Зачем ты добавляешь в свои классы это свойство ?
RTTI сама все сделает.

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


 
aka   (2012-12-28 16:42) [18]


> Сергей М. ©   (28.12.12 16:28) [17]

Задача такая - это свойство должно быть и все.

RTTI, а что она сделает?
Если нужно работать с массивом указателей на массу объектов. Нужно в начале узнать на что указывает конкретный елемент PtrObjArray[I], для этого и используется это поле.

Чтобы разыменовать указатель - нужно знать какой тип он имеет и как это узнать заранее, ведь массив имеет ссылки на не однотипные объекты


 
RWolf ©   (2012-12-28 16:48) [19]

ООП же, ну.
полиморфизм, виртуальные функции — зачем изобретать кривые велосипеды?


 
Сергей М. ©   (2012-12-28 17:03) [20]


> Задача такая - это свойство должно быть и все.


Ты сам себе поставил эту задачу или на этот счет было конкретное постановление партии и правительства ?


> RTTI, а что она сделает?


Она вот чего сделает:

if SomeObject is TClass1 then
 //.. в SomeObject - объект класса TClass1
else if SomeObject is TClass2 then
 .. в SomeObject - объект класса TClass3
else if SomeObject is TClass3 then
 .. в SomeObject - объект класса TClass3


 
aka   (2012-12-28 17:20) [21]

Закрывайте тему.

мне нужно так if (TCustomObject(PtrObjArray[i]).ObjType="???


> Она вот чего сделает:
>
> if SomeObject is TClass1 then
>  //.. в SomeObject - объект класса TClass1
> else if SomeObject is TClass2 then
>  .. в SomeObject - объект класса TClass3
> else if SomeObject is TClass3 then
>  .. в SomeObject - объект класса TClass3

")

это не подходит по причине того, что один класс может иметь разный ObjType - ну так уж получилось)


 
Сергей М. ©   (2012-12-28 17:33) [22]


> один класс может иметь разный ObjType


Упарил ты своими ObjType и rectype)

Если ты уж развернул оглобли в сторону классов и объектов, то не нужны они вообще - информацию о типах компилятор сам создаст и поместит в RTTI.

Вот так это будет выглядеть:

if ObjArray[i] is TClass1 then
  TClass1(ObjArray[i]).Property1 ...
else if SomeObject is TClass2 then
  TClass2(ObjArray[i]).Property3 ...
else if SomeObject is TClass3 then
  TClass3(ObjArray[i]).Property3 ...


 
aka   (2012-12-28 17:46) [23]

Короче закрывайте тему.


 
aka   (2012-12-28 17:51) [24]

Мне на ДельфиКиндом написали что вариант первый с записями шикарный по реализации ). Так что так. Не верите? - посмотрите сами.


 
знайка   (2012-12-28 18:29) [25]

не верим, и смотреть даже не будем. :)


 
Сергей М. ©   (2012-12-28 21:55) [26]


> Мне на ДельфиКиндом написали


Мало ли кто на кого написал после того как ты тему закрыл)


 
Rouse_ ©   (2012-12-28 23:30) [27]


> aka   (28.12.12 17:46) [23]
> Короче закрывайте тему.

Эт можно...



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

Текущий архив: 2013.09.15;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.006 c
3-1292492845
RWolf
2010-12-16 12:47
2013.09.15
ClientDataSet: Insufficient memory for this operation


15-1365280202
Юрий
2013-04-07 00:30
2013.09.15
С днем рождения ! 7 апреля 2013 воскресенье


2-1357246105
Irmantukas
2013-01-04 00:48
2013.09.15
Несрабатывает имитация нажатия левой кнопки мышки...


15-1365423706
ВВВ
2013-04-08 16:21
2013.09.15
Syntax Check - Hotkey.


2-1356592827
Pcrepair
2012-12-27 11:20
2013.09.15
Проблемы с потоками при закачке страниц