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

Вниз

ООП - корректный тип для экземпляра объекта   Найти похожие ветки 

 
Misha123   (2004-09-15 12:45) [0]

Доброго дня, мастера.
Уже задавал вопрос - про указатель на свойство - спасибо большое за ответы (лучше поздно, чем никогда...)!

Очередной вопрос опять не блещет ясностью выражения мысли, сразу предупреждаю и приношу извинения... :)

Собственно вопрос (сначала постановка задачи):

Есть:
tvec = array of double;

TPhase = class
private
....
sxi: tvec;
function getxi(aindex: byte): double; virtual;
procedure setxi(newValue: double; aindex: byte); virtual;
public
....
property xi[aindex]: tvec
constructor create(p1, p2: double);
destructor destroy; override;
end;

TLPhase = class (TPhase)
private
....
procedure setxi(newValue: double; aindex: byte); override; //другой алгоритм записи
public
...
function Gf: double; virtual;
function G: double;
constructor create(p1, p2, p3, p4: double);
destructor destroy; override;
end;

TLlinePhase = class (TLPhase)
private
...
function Gf: double; override; //по-другому считает
public
...
constructor create(p1, p2, p3, p4: double);
destructor destroy; override;
end;

constructor TPhase.create;
begin
inherited;
field1:=p1;
field2:=p2;
end;

....

function TPhase.getxi;
begin
result:=sxi[aindex];
end;

constructor TLPhase.create;
begin
inherited create(p1, p2);
field3:=p3;
field4:=p4;
end;

....

constructor TLlinePhase.create;
begin
inherited;
end;

....

в другом юните делаю менюшку (хочу чтобы при выборе юзера менялся экземпляр класса на выбранный) и пишу:

var
phaseObj: TPhase;

implementation

....

procedure onMenu1Select;
begin
phaseObj:=nil; //phaseObj.free почему-то не уничтожает объект... уничтожает только поля класса
case menuitem of
....//инициализация переменных, передаваемых конструктору
0: phaseObj:=TLPhase.create(p1, p2, p3, p4);
1: phaseObj:=TLlinePhase.create(p1, p2, p3, p4);
end;

(эту процедурку загоняю в formcreate)
Что происходит: при первом запуске, т.е. когда отрабатывает formcreate - все нормально;
как только меняю объект - при запуске какого-то расчета - ошибка при чтении значения из sxi[i].
Если не делать nil - читает, но читает что sxi[i]=0 - хотя до этого точно было присвоено значение:
phaseObj.xi[i]:=0.44; (xi -> свойство объявлено в TPhase -> sxi)

второй вариант:
var
phaseObj: TObject;

В этом случае присвоения адреса переменной при создании объекта не происходит... т.е. пустой экземпляр
nil получается.... приведение типов (кстати и в первом варианте) делаю, например:
(phaseObj as TLPhase).xi[0]:=0.45; //тут в общем-то написал - используется даже если phaseObj
закриейтился как TLlinePhase.

В принципе если полный код :) нужно посмотреть - могу привести (но кто будет смотреть? :) )

Сразу большое спасибо за все и любые ответы!


 
Skier ©   (2004-09-15 12:52) [1]


> phaseObj.free почему-то не уничтожает объект...
> уничтожает только поля класса

Как же это выяснилось ?!


 
Dynamic ©   (2004-09-15 13:25) [2]

Приведи код procedure setxi(), есть ли там SetLength()??


 
Misha123   (2004-09-15 15:27) [3]

skier - выяснилось очень просто (может быть просто некорректно выразил свою мысль?...) - в отладчике... - объект есть, все поля (динамические, статические и т.д.) - пустые.

Dynamic - привожу (нет - сразу устанавливается в конструкторе):

procedure TLPhase.setxi;
begin
sxi[aindex]:=newValue;
sip{это другое поле класса}=c_ip; //расчет другого параметра, зависящего от sxi (но там нет изменения sxi)
end;

я контроллирую состояние массива и гарантирую :), что выхода за пределы маасива нет.
Более того, наблюдал (правда не в этом случае :) ): если в отладчике я нахожусь в коде в пределах TLPhase - в watch я вижу значение sxi, как только попадаю в getxi - sxi показывается 0, хотя перед этим я записывал в sxi какое-то значение:
phaseObj:=TLlinePhase.create(p1, p2, p3, p4); //p1 определяет длину массива
(phaseObj as TLPhase).xi[0]:=0.47;
кстати: почему в таком коде при наведении указателя на phaseObj в отладчике я вижу только список переданных параметров p1, p2, p3, p4.
А если я пишу:
var phaseObj: TLPhase
phaseObj:=TLPhase.create(p1, p2, p3, p4);
- в этом случае в phaseObj я вижу ВСЕ поля, методы, их значения, адреса и т.д.?


 
VMcL ©   (2004-09-15 16:19) [4]

>>Misha123  (15.09.04 12:45)
>>Misha123  (15.09.04 15:27) [3]

>phaseObj.free почему-то не уничтожает объект... уничтожает только поля класса

>объект есть, все поля (динамические, статические и т.д.) - пустые.

Ошибаешься. После вызова деструктора объект уничтожается, т. е. автоматически освобождаются все его поля, которые являются ссылками на объекты с управляемым временем жизни (длинные строки, динамические массивы, экземпляры интерфейсов, ...) и освождается память, занятая под сам объект. Скорее всего, то, что ты видишь в отладчике, - это его "след", поскольку делфийский менеджер памяти ещё не вернул память системе.


 
Misha123   (2004-09-15 17:52) [5]

хм... наверное так и есть...
Т.е. nil использовать не стоит, или по шарабану?

А другие вопросы? :)


 
basken   (2004-09-15 18:49) [6]

Желательно освобождать память

if Assigned(phaseObj) then
 FreeAndNil(phaseObj)


 
VMcL ©   (2004-09-15 19:21) [7]

>>basken  (15.09.04 18:49) [6]

>if Assigned(phaseObj) then

Это лишнее, поскольку функция FreeAndNil вызывает метод Free. Следует писать просто: FreeAndNil(SomeObject);


 
basken   (2004-09-15 19:52) [8]


> VMcL ©   (15.09.04 19:21) [7]
>
> Это лишнее, поскольку функция FreeAndNil вызывает метод
> Free. Следует писать просто: FreeAndNil(SomeObject);


Зачем вызывать FreeAndNil(SomeObject), когда not Assigned(SomeObject) ?


 
icWasya ©   (2004-09-15 20:09) [9]

[8] Зачем вызывать FreeAndNil(SomeObject), когда not Assigned(SomeObject) ?
а что бы не загромождать код
внутри в  FreeAndNil уже есть проверка на Nil


 
misha123   (2004-09-15 20:44) [10]

то есть проблема в том, что неправильно освобождается переменная?
у меня все-таки подозрение, что не в этом проблема - даже если я не освобождаю вообще - работает но за счет того что в свойстве класса стоит 0 (см. выше ) - просто тупо график строится по нулевой оси....


 
VMcL ©   (2004-09-16 13:43) [11]

>>basken  (15.09.04 19:52) [8]

>Зачем вызывать FreeAndNil(SomeObject), когда not Assigned(SomeObject) ?

Неправильный вопрос. Правильный: зачем вызывать if Assigned(SomeObject), если эта проверка выполняется в методе TObject.Free, который вызывается из FreeAndNil?

Если хочешь сделать так, шоб було супер-пупер-быстро, то пиши:
if Assigned(SomeObject) then
begin
 SomeObject.Destroy;
 SomeObject := nil;
end;


Только смысла в этом я не вижу.


 
misha123   (2004-09-17 10:04) [12]

ок, спасибо. А вообще, если у меня TPhase, TLPhase и т.д. наследники - какого типа должна быть переменная чтобы она понимала все эти классы? Если я пишу TObject - конструктор адрес в нее не дает, если TPhase - проблемы см. выше....


 
Amoeba ©   (2004-09-17 10:44) [13]


> какого типа должна быть переменная

TPhase

А проблемы у тебя в твоем коде, где-то в 17-й строке. Разбирайся с отладчиком.


 
basken   (2004-09-17 10:47) [14]

Можно так
....
var
 Obj: TObject;
begin  
...
 if Obj is TLPhase then
   TLPhase(TLPhase).MethodTLPhase;
...
end;


 
misha123   (2004-09-17 13:06) [15]

спасибо за ответы



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

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

Наверх




Память: 0.51 MB
Время: 0.036 c
4-1093797216
DeMoN_Astra
2004-08-29 20:33
2004.10.03
Диалоговое окно - Вопроса


4-1093079315
Arnold
2004-08-21 13:08
2004.10.03
Как узнать количество запущенных процессов???


14-1095161406
frankvi
2004-09-14 15:30
2004.10.03
PDF Viewer


3-1094019462
bSava
2004-09-01 10:17
2004.10.03
Непонятное поведение FB1.5


4-1093381845
WELLiON
2004-08-25 01:10
2004.10.03
Отрубить клаву, мышь и монитор.