Форум: "Основная";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];
ВнизООП - корректный тип для экземпляра объекта Найти похожие ветки
← →
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 я вижу ВСЕ поля, методы, их значения, адреса и т.д.?
phaseObj:=TLPhase.create(p1, p2, p3, p4);
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.037 c