Форум: "Основная";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];
Вниз"Устаревший стиль объекта" Найти похожие ветки
← →
Key (2007-10-13 09:56) [0]Уважаемые мастера
Работаю с нек. компонентом. В нем приходится работать с записями. Сообщаешь ему размер этой записи, он сам ее путем GetMem() у себя формирует, куда надо вставляет и когда надо, возвращает на нее указатель. При разрушении - вызывает FreeMem()
Также у этого хитрого компонента предусмотрены события InitItem и FreeItem, выполняющие функции конструктора и деструктора соответственно. Не знаю, почему так, не спрашивайте. :)
Работает нормально, но после работы с классами очень неуютно чувствуешь себя с record. Ни тебе метод написать, ни свойство. Появилась идея заменить record на .... "устаревший" object. Что интересно, работает нормально тоже. И даже свойство вызывается. И память чистится правильно. Фактически это аналог экземпляра класса в C++ (не указателя на него, а расположенного, скажем, в стеке). Разве что конструкторы и деструкторы не вызываются :(
Но Delphi меня начало предупреждать, что мол
"Unsafe type "TXSDTreeRec: old style object""
Значит ли это, что пользоваться object нельзя потому, что их поддержка в следующих версиях отсутствует? Или работа их не гарантируется? Или еще какие-то подводные камни?
Спасибо.
← →
Leonid Troyanovsky © (2007-10-13 15:41) [1]
> Key (13.10.07 09:56)
> Работает нормально, но после работы с классами очень неуютно
> чувствуешь себя с record. Ни тебе метод написать, ни свойство.
> Появилась идея заменить record на .... "устаревший" object.
Напиши лучше свой компонент для управления чужим.
Например, ссылки на распределенные записи будет
держать TList и т.д.
Не забудь про Notification; override для того, чтобы
всегда иметь валидную ссылку на чужой.
--
Regards, LVT.
← →
просто так (2007-10-15 13:16) [2]>>Работает нормально
Пока у обжекта нет виртуальных методов он не отличается от рЕкорда
>>object нельзя потому, что их поддержка в следующих версиях отсутствует?
а вот это наврятли
← →
Anatoly Podgoretsky © (2007-10-15 14:10) [3]
> а вот это наврятли
А вот это запросто, Борланд предупреждал.
← →
Sapersky (2007-10-15 20:23) [4]Наследование в сочетании с managed-типами (aka типы с управляемым временем жизни - длинные строки, дин. массивы, варианты, интерфейсы) может привести к проблемам:
TFirstObj = object
s : String;
end;
TSecondObj = object (TFirstObj)
// ...
end;
TSecondObj ничего не знает об s : String; и не сможет её корректно инициализировать/финализировать. Хотя проблема не фатальная - например, в библиотеке KOL она решена созданием объектов через New (при этом поля заполняются нулями) и уничтожением всех строк вручную в деструкторе (s := "").
Прискорбно жаль, что Борланд/КодГир ничего не пишут в хелпе по этому поводу (кроме their use is not recommended).
М-да, только сейчас сообразил: если ваш супер-компонент выделяет память через GetMem, ему managed-типы вообще противопоказаны. Ну разве что обрабатывать их вручную в InitItem и FreeItem - но какие они после этого managed.
← →
просто так (2007-10-15 21:32) [5]>>TSecondObj ничего не знает об s : String
с чего это вдруг ничего не знает? на то оно и наследование чтоб знать))
← →
DVM © (2007-10-15 22:41) [6]у меня в BDS2006 один модуль как то не хотел компилироваться, потому, что там вместо class было объявлено object. Просто не компилировался и все. Писал внутренняя ошибка и курсор вставал на завершающую точку в модуле. Пришлось поменять. А в предыдущих версиях все нормально компилировалось.
← →
Sapersky (2007-10-16 02:46) [7]с чего это вдруг ничего не знает?
В основном потому, что на момент создания object managed-типов ещё не было в природе. А потом - то ли было в принципе невозможно, то ли не захотели менять внутреннюю структуру object, чтобы не поломать обратную совместимость.
Можете проверить:
Var fObj : TFirstObj;
sObj : TSecondObj;
fObj.s := ... ;// всё нормально
sObj.s := ... ;// AV
← →
просто так (2007-10-16 07:10) [8]>>у меня в BDS2006 один модуль как то не хотел компилироваться, потому, что там вместо class было объявлено object.
думаю причины были совсем не в object. с ними всё ок в BDS2006.
>>sObj.s := ... ;// AV
врешь и не краснеешь)). хотя может дело в коментарии
fObj.s := ... ;// всё нормально
sObj.s := ... ;// всё нормально
так всё работает)) может ты использовал виртуальные методы до вызова конструктора?
← →
просто так (2007-10-16 07:13) [9]>>Sapersky
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TFirstObj = object
s : String;
end;
TSecondObj = object (TFirstObj)
end;
Var fObj : TFirstObj;
sObj : TSecondObj;
begin
fObj.s := "1" ;// всё нормально
sObj.s := "2" ;// всё нормально
end.
Проверь еще раз
← →
просто так (2007-10-16 07:36) [10]>>TSecondObj ничего не знает об s : String; и не сможет её корректно инициализировать/финализировать. Хотя проблема не фатальная - например, в библиотеке KOL она решена созданием объектов через New (при этом поля заполняются нулями) и уничтожением всех строк вручную в деструкторе (s := "").
так сделано совсем не по этому. для динамически созданых рекордов/обжектов присваивание стрингов/дин.массивов := "", обязательно иначе будут мемлики. для переменных объявленных в секции var за нас это сделает компилятор
← →
Sapersky (2007-10-16 09:25) [11]AV будет с локальными переменными.
С глобальными, впрочем, тоже не всё гладко - будет утечка.
для динамически созданых рекордов/обжектов присваивание стрингов/дин.массивов := "", обязательно
Если через New/Dispose(Free), то не обязательно, во всяком случае для TFirstObj. Если через GetMem/FreeMem - то да.
← →
просто так (2007-10-16 09:34) [12]>>AV будет с локальными переменными. С глобальными, впрочем, тоже не всё гладко - будет утечка.
AV не будет. если конечно не обращаться локальному к объекту после его выхода из зоны видимости. но это другая песня.
Поясни пожалуйста по утечке
← →
Sapersky (2007-10-16 09:59) [13]Я же писал: TSecondObj ничего не знает об s : String; и не сможет её корректно инициализировать/финализировать.
Т.е. в локальной переменной sObj.s при входе в область видимости будет мусор. При попытке присвоить ей что-нибудь компилятор попытается "освободить" старую "строку", со всеми печальными вытекающими.
В глобальной будет nil, поэтому обойдётся без AV. Но корректно освободить память компилятор не сможет. Потому как информация о managed-типах у объектов и классов хранится только для текущего уровня иерархии, но если по классу легко получить его предка, то как это сделать для объекта - даже матёрые приКОЛисты не смогли додуматься, насколько я помню. А компилятор, в принципе, использует те же (ну или почти те же) средства.
← →
просто так (2007-10-16 10:06) [14]Специально токачто попробовал вышеизложенный пример завернутый в процедуру. всё работает. если переменная объявлена в var секции она инициализируется корректно и TSecondObj прекрасно знает об s. проблемы могут возникнуть только при динамическом создании, для их решения можно завести отдельный конструктор который будет делать принудительное pointer(s):=nil;
← →
Sapersky (2007-10-16 10:25) [15]Какой Delphi? У меня в 5-м AV.
Код полностью:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TFirstObj = object
s : String;
end;
TSecondObj = object (TFirstObj)
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
Var fObj : TFirstObj;
sObj : TSecondObj;
begin
fObj.s := "1";
sObj.s := "2";
end;
end.
← →
DVM © (2007-10-16 11:53) [16]
> просто так (16.10.07 07:10) [8]
> >>у меня в BDS2006 один модуль как то не хотел компилироваться,
> потому, что там вместо class было объявлено object.
> думаю причины были совсем не в object. с ними всё ок в BDS2006.
>
Может и не в object, но скомпилировался, только после замены на class.
Вот он кстати (модуль не мой). http://dvmuratov.narod.ru/CpuInfo.pas
Вот в таком виде он не компилируется.
← →
просто так (2007-10-16 14:06) [17]>>Sapersky
Убедил. у меня AV нету но в s мусор...
я проверял в консольном приложении, в s всё ок, но при добавлении полей в TFirstObj тоже появился мусор. сыплюголову пеплом)))
делаю большой проект на обжектах, ниразу с этим не сталкивался, т.к. не использую локальные сложные переменные
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c