Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
9-1165348759
Vladimir1984
2006-12-05 22:59
2008.01.13
RGB, CMY GetRValue подбор цветов перехода...


15-1197208148
Questioner_
2007-12-09 16:49
2008.01.13
Нужно написать программу...


15-1196969166
Koss
2007-12-06 22:26
2008.01.13
проблема с добовалением компонентов


2-1197710104
петрович07
2007-12-15 12:15
2008.01.13
курсор в пределах формы


15-1197263105
class_
2007-12-10 08:05
2008.01.13
При просмотре небольшого ролика в Интернет





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский