Форум: "Основная";
Текущий архив: 2002.12.05;
Скачать: [xml.tar.bz2];
ВнизВопрос из Областии Объектно Орентированного Программирования Найти похожие ветки
← →
Misha (2002-11-14 13:39) [0]У меня есть класс TOb=class(TObject)
и его наследует другой класс TObN
и в этом классе существует поле MOb представляющее собой массив
экземпляров класса TOb.
Вопрос заключается в том, как написать конструктор
для класса TObN, чтобы инициализировать поле MOb:
Либо в качестве параметра конструктора задавать массив экземпляров уже инициализированных TOb
Или же есть какой-нибудь другой более удобный способ
← →
Alx2 (2002-11-14 13:41) [1]constructor TObn.Create;
begin
inherited;
initializeMob; - инициализируем
end;
← →
Misha (2002-11-14 13:42) [2]И ещё один вопросик:"Где в сети можно найти подробную документацию на русском языке по ООП в Delphi"
← →
Misha (2002-11-14 13:45) [3]Alx2,спасибо. Как я понял в initializeMob в качестве параметра
следует задавать массив экземпляров класса TOb уже инициализиро-
ванных?
← →
Skier (2002-11-14 13:47) [4]>Misha
1) Для хранения ссылок на экз. класса TOb
используй TList (или TObjectList) или их потомки
И можно ещё использовать индексное свойство.
что-то типа :
property MOb[Index : Integer] : TOb read GetOb write SetOb;
2) Если в потомке TOb должна быть вожнозность
инициализировать экз. класса TOb "из вне" то
надо это делать через парамерт конструктора потомка TOb
Если такая возможность не предусматривается,то инициализируй
экз. класса TOb в теле конструктора потомка TOb
← →
Misha (2002-11-14 13:50) [5]А для добавления к TList нового элемента следует использовать
List.Add(Ob1)
или
List.Add(Ob1^)
← →
Alx2 (2002-11-14 13:51) [6]>Misha (14.11.02 13:45)
А вон про что...
Если Mob уже инициализировал предок, зачем без нужды их переинициализировать? Ведь в начале вызывается коснтруктор предка (слово inherited) в котором (если она есть, конечно)выполнится ранее написанная для Tob инициализация объектов Mob
← →
Misha (2002-11-14 14:10) [7]Alx2, т.е. если я задаю массив экземпляров класса TOb1, то
Inherited произведёт инициализацию поля MOb(являющегося
массивом экземпляров TOb1)экземпляра
класса TObN, являющегося наследником TOb1?
Или как?
← →
Alx2 (2002-11-14 14:14) [8]>Misha (14.11.02 14:10)
Inherited вызовет конструктор предка. То есть, если у тебя TObN потомок TOb1 и написано
constructor TObN.create;
begin
inherited; - вот это место вызовет TOb1.Create.
................
.................... // твои другие действия
end;
Если же конструктор совсем не описан в TOBn то при создании будет вызываться сразу конструктор TOb1.
Механизм посмотри в дебагере с помощью F7
← →
Misha (2002-11-14 18:14) [9]Skier, как я понял, ты предлагаешь мне использовать для хранения
нескольких экземпляров класса TOb1 в поле класса TObNсписок (TList) ссылок на них, тогда инициализация
этого списка будет иметь вид ?:
for i:=1 to N do
List.Add(Ob1[i]^);
Вопрос втом, что мне в конструктор передавать как параметр
массив (ссылок на экземпляры класса TOb1)?
B ещё один вопросик, как и где описывать друзей класса, если можно, то на кратком примере.
← →
Skier (2002-11-15 10:25) [10]>Misha
Такие вопросы :
1) Как ты всё-таки собираешься инициализировать (создавать)
экз-ры. класса TOb, передавать уже созданнные "из вне" в
параметре конструктора или создавать их в теле конструктора ?
Ты определился ?
2)
> B ещё один вопросик, как и где описывать друзей класса
???!!! Поясни !
← →
mvg_first (2002-11-15 11:59) [11]Друзья (friend функции) - в дельфине отсутствуют, вместо этого существует такое понятие как декларация двух класов в одном Юните :) Тогда эти "друзья" будут иметь доступ к protected методам друг друга :)
Вот так Вот :)
← →
Misha (2002-11-18 10:13) [12]Skier, я собираюсь собираюсь инициализировать (создавать)
экз-ры. класса TOb ,
вне конструктора класса TObN(одним из свойств которого является
массив или как ты мне советовал список ссылок на экземпляры класса TOb). Затем я собираюсь передать этот массив (или список)
экземпляров класса в конструктор класса TObN, как параметр.
Посоветуй мне пожалуйста, стоит и если да, то как создать и использовать список ссылок на экземпляры класса TOb, который
(список ссылок)являлся бы свойством TOb.
Или же лучше вместо ссылок в списке хранить копии экземпляров класса TOb.
← →
Skier (2002-11-18 10:51) [13]>Misha
Ссылки на экз-ры. класса TOb (в конструктор TObN) можно передавать через открытый массив и уже в конструкторе TObN копировать ссылки.
...И получится примерно следующее :
TOb = class
//.............
end; //TOb
TObList = class(TList)
//.............
//список объектов TOb.
end; //TObList
TObN = class(TOb)
private
FObList : TObList;
procedure PutOb(AIndex : Integer; AItem : TOb);
function GetOb(AIndex : Integer) : TOb;
public
constructor Create(AObjs : array of TOb);
destructor Destroy; override;
property Obs[Index : Integer] : TOb read GetOb write PutOb; default;
end; //TOb
{ TObN }
constructor TObN.Create(AObjs: array of TOb);
var
ii : Integer;
begin
inherited Create;
FObList := TObList.Create;
for ii := Low(AObjs) to High(AObjs) do begin
//............копирование ссылок...
if AObjs[ii] <> nil then FObList.Add(AObjs[ii]);
end; //for
end;
destructor TObN.Destroy;
begin
FreeAndNil(FObList);
inherited Destroy;
end;
function TObN.GetOb(AIndex: Integer): TOb;
begin
//...стоит сделать проверку...
Result := FObList.Items[AIndex];
end;
procedure TObN.PutOb(AIndex: Integer; AItem: TOb);
begin
//...стоит сделать проверку...
FObList.Items[AIndex] := AItem;
end;
Использование :
procedure TForm1.Button1Click(Sender: TObject);
var
AOb1 : TOb;
AOb2 : TOb;
AObN : TObN;
begin
AOb1 := TOb.Create;
AOb2 := TOb.Create;
try
AObN := TObN.Create([AOb1, AOb2]);
try
//..............
finally
FreeAndNil(AObN);
end; //try
finally
FreeAndNil(AOb1);
FreeAndNil(AOb2);
end; //try
end;
← →
Misha (2002-11-18 12:11) [14]Спасибо, Skier.
Что означает эта строчка
property Obs[Index : Integer] : TOb read GetOb write PutOb; default;
← →
Skier (2002-11-18 12:42) [15]>Misha
Это объявление свойства,оно является свойством-массивом (см. Array properties в Hepl-e).
Обращаясь к этому свойству ты получишь экземпляр класса TOb, созданного "во вне" (кстати не забудь эти экземпляры потом
освободить), короме того это свойство является дефолтным (такое свойство в классе может быть только одно(!) ),тобиш
ты можешь обращаться к нему, не используя точечную нотацию,т.е.
1)"обычное" обращение - ObN.Obs[I]
2) обращение без точечной нотации - ObN[I], где
ObN - это экземпляр класса TObN.
← →
Misha (2002-11-19 12:43) [16]Спасибо, Skier.
У меня к тебе есть вопросы:
1)В коде который ты мне прислал есть такой класс:
TObList = class(TList)
//.............
//список объектов TOb.
end; //TObList
Можно ли использовать все его методы и свойства для хранения
ссылок на экземпляры класса TOb или же надо их переопределять
2)Как высвободить память из-под массива экземляров классов
TOb.
Я выделил под него память использовав SetLength(ATMy,2);
(где ATMy- массива экземляров классов TOb),
а затем
ATMy[1] := TOb.Create;
ATMy[2]:= TOb.Create;
далее я всё делал как ты мне посоветовал в
procedure TForm1.Button1Click(Sender: TObject);
но в самом конце я попробовал освободить память следующим
образом:
For i:=Low(ATMy) to High(ATMy) do FreeAndNil(ATMy[i]);
Но в процессе выполнения программы происходит ошибка
"Invalid pointer operator"
← →
Skier (2002-11-19 12:50) [17]>Misha
1)
> Можно ли использовать все его методы и свойства для хранения
> ссылок на экземпляры класса TOb или же надо их переопределять
Можно и не переопределять, но тогда ты должен будешь
кастить (приводить типы), т.к. св-во TList.Items- имеет тип
Pointer.
2)
ATMy[ 0] := TOb.Create;
ATMy[ 1]:= TOb.Create;
Динамические (и открытые) массивы индексируются с нуля
← →
Misha (2002-11-19 13:53) [18]Спасибо,Skier, теперь работает.
У меня возник ещё такой вопрос выполнив код
For i:=Low(ATMy) to High(ATMy) do FreeAndNil(ATMy[i]);
я полностью освобожу память или надо сделать ещё чего-нибудь,
типа ATMy=nil ?
← →
Skier (2002-11-19 14:24) [19]>Misha
procedure YourProc;
var
ATMy : TSomeDynamicArray
begin
//работа с ATMy
end;
//<------------------ здесь ATMy освободит Delphi.
//т.к. Delphi считает ссылки, на ATMy, так же как и на строки.
//И если кол-во ссылок = 0, то дин. массив освобождается.
Хотя ты можешь освобождать дин. массив - явно (хуже не будет :) ) :
a) ATMy := nil или б) Finalize(ATMy)
← →
Misha (2002-11-19 14:53) [20]Skier,спасибо тебе.
Что надо сделать в
TObList = class(TList)
//.............
//список объектов TOb.
end; //TObList
чтобы свойствойство Items имело тип указатель на TOB, а не
Pointer. И стоит ли это делать, либо обойтись кастингом.
← →
Skier (2002-11-19 15:04) [21]>Misha
type
TObList = class(TList)
protected
procedure Put(Index : Integer ; Item : TOb);
function Get(Index : Integer) : TOb;
public
function Add(Item : TOb) : Integer;
property Items[Index: Integer] : TOb read Get write Put; default;
end; //TObList
Реализация :
procedure TObList.Put(Index : Integer ; Item : TOb);
begin
inherited Put(Index, Item);
end;
function TObList.Get(Index : Integer) : TOb;
begin
Result := inherited Get(Index);
end;
function TObList.Add(Item : TOb);
begin
Result := inherited Add(Item);
end;
> И стоит ли это делать, либо обойтись кастингом.
Это тебе решать...но я бы всё-таки сделал TObList,
чтобы каждый раз не кастить...
← →
Misha (2002-11-19 15:46) [22]Skier, тестируя программу по шагам, я обнаружил, что
после выполнения процедуры
constructor TObN.Create(AObjs: array of TOb);
var
ii : Integer;
begin
inherited Create;
FObList := TObList.Create;
for ii := Low(AObjs) to High(AObjs) do begin
//............копирование ссылок...
if AObjs[ii] <> nil then FObList.Add(AObjs[ii]);
end; //for
end;
FObList -пуст,т.е. он =(), хотя
в procedure TForm1.Button1Click(Sender: TObject);
я создал массив экземпляров класса TOB из двух объектов, и он
был не пуст.
TOB=class(TObject)
private
FMyField:Integer;
public
{методы......}
end;
Почему это произошло?
← →
Skier (2002-11-19 15:50) [23]>Misha
=() - это как раз и значит что он не пуст, если хочешь
в этом убедиться после цикла копирования ссылок - поставь
ShowMessage(IntToStr(FObList.Count));
← →
han_malign (2002-11-19 15:53) [24]А ты массив в TObN.Create()- передал?
Если нет - то вызвался Create предка.
З.Ы. FObN:=TObN.Create([TOB.Create,TOB.Create])
← →
Misha (2002-11-26 15:55) [25]Спасибо, Skier.
А как явно приводить типы, я делаб так
i:=PTOb(FObN.TObList.Items[1]).put
где PTOb - указатель на ТOb
этим самым я хочу получить значение одного из свойств (при
помощи его метода Put) у экземпляра класса TOb c индексом 1,
в результате я получаю какое-то непонятное число.
В данном примере я не использовал переопределение методов
класса TObList.
И ещё один вопрос, как в открытый динамический маасив объектов добавить ещё один или удалить ещё один объект с минимально возможными затратами памяти
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.12.05;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.011 c