Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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:=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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.044 c
6-1090728007
DelphiN!
2004-07-25 08:00
2004.10.03
Ссылка на объект для скачивания


4-1092836312
R1
2004-08-18 17:38
2004.10.03
Диалог свойств файла (ShellExecuteEx)


1-1095440841
Scorpion
2004-09-17 21:07
2004.10.03
Приоритеты потока


11-1081013421
Delphi5.01
2004-04-03 21:30
2004.10.03
TKOLPaintBox


3-1094166069
fif
2004-09-03 03:01
2004.10.03
базы данных database в сети





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский