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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.002 c
15-1365042070
Думкин_
2013-04-04 06:21
2013.09.15
404 - всех с Днем!


15-1365407634
xayam
2013-04-08 11:53
2013.09.15
Мелодия


6-1269263709
DevilDevil
2010-03-22 16:15
2013.09.15
Считать HTML c VKontakte


15-1365366603
Юрий
2013-04-08 00:30
2013.09.15
С днем рождения ! 8 апреля 2013 понедельник


15-1365336685
Разведка
2013-04-07 16:11
2013.09.15
как создать сгенерировать UUID





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