Форум: "Начинающим";
Текущий архив: 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