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

Вниз

Вопрос из Областии Объектно Орентированного Программирования   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.013 c
7-14846
crush_fm
2002-10-01 20:37
2002.12.05
CPU


8-14696
SERCAM
2002-08-18 23:52
2002.12.05
Как сделать позитив с негатива цветной плёнки?


14-14770
Filat
2002-11-13 18:09
2002.12.05
Как обойти??!! Не ставится Delphi 5 на Windows 2000 Adv. Server!


1-14603
Arhangel
2002-11-24 11:22
2002.12.05
Размер текстового файла?


14-14815
Bboy tn
2002-11-14 23:16
2002.12.05
Ничего не понимаю в мониторах SAMSUNG