Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
ВнизКак правильн вызвать Destroy? Найти похожие ветки
← →
Константин (2010-04-02 15:00) [0]Как правильно вызвать Destroy у объекта, который унаследован от TObjectList и в котором есть свойство Strings TStringList
Делаю так:
destructor Destroy;
....
destructor TOMyObjtct.Destroy;
begin
Strings.Free;
inherited;
end;
Не пойму. В таком варианте вроде работает, но непонятно как память освобождает. А вот если объявить деструктор как
destructor Destroy; override;
То в него заходит деббагер но ошибка на вызове деструктора предка!
← →
Омлет © (2010-04-02 15:01) [1]какая ошибка?
← →
Константин (2010-04-02 15:06) [2]на inherited; Access Violation ....
← →
Демо © (2010-04-02 15:08) [3]Для начала замени Strings на FStrings, например, так как Strings в предке может использоваться.
← →
Константин (2010-04-02 15:15) [4]
> Демо © (02.04.10 15:08) [3]
почти так и произошло, но пример был абстрактный, естественно в оригинале так нечиго неназывалось. Уже нашел - я переопределил Clear у TObjectList=>TList и поэтому в TList.Destroy не ходило ))
← →
Anatoly Podgoretsky © (2010-04-02 15:20) [5]> Константин (02.04.2010 15:00:00) [0]
Мы очень любим людей, которые говорят у меня ошибка
← →
Anatoly Podgoretsky © (2010-04-02 15:21) [6]> Константин (02.04.2010 15:15:04) [4]
А нафига нам обсуждать несуществующий код, вместо реального?
← →
Игорь Шевченко © (2010-04-02 15:24) [7]
> А вот если объявить деструктор как
> destructor Destroy; override;
так всегда надо объявлять
← →
Константин (2010-04-02 15:33) [8]
> Anatoly Podgoretsky © (02.04.10 15:20) [5]
это положительный отзыв?
> Anatoly Podgoretsky © (02.04.10 15:21) [6]
Ну я не подумал что в данном случае поле Strings может привести к конфликтам со свойствами TObjectList или TList
;)
← →
Anatoly Podgoretsky © (2010-04-02 17:51) [9]Тогда при компиляции без destroy должно было выдать предупреждение, которое обязательно к прочтению и осмыслению.
← →
Константин (2010-04-02 21:08) [10]Anatoly Podgoretsky
> Ну я не подумал что в данном случае поле Strings может привести
> к конфликтам со свойствами TObjectList или TList
> ;)
Это прикол. Какой может быть Strings в TObjectList или TList?
Просто смысл выводить тут названия если можно просто объяснить псевдо-кодом?
Кстати и без destroy я не компилировал, а хинты и варнинги всегда смотрю!
← →
_Юрий © (2010-04-03 09:57) [11]У тебя тут скорее всего было двойное разрушение
например, ты сам разрушил объект, который также входил в ObjectList был освобожден вместе с ним.
> destructor Destroy; override;
Если объявить его без override, это приведет например к тому, что при разрушении элемента, входящего в ObjectList, твой деструктор просто не будет вызван.
← →
Константин (2010-04-03 20:44) [12]я уже написал, что был перезаписан Clear и Destroy у TList не вызывался
← →
brother © (2010-04-05 06:18) [13]> Clear и Destroy у TList не вызывался
без кода - не вижу связи... + согласен с [3]
← →
Константин (2010-04-05 17:43) [14]
> brother © (05.04.10 06:18) [13]
Принципиально спрошу, где не видно связи. Открой TObjectList и TList найдит там хот одно поле Strings, и посмотри на деструктор последнего. Мой код в первом посте.
← →
_Юрий © (2010-04-05 19:35) [15]
> я уже написал, что был перезаписан Clear и Destroy у TList
> не вызывался
Ну я тогда тоже принципиально спрошу - каким образом в данном примере неосвобождение памяти могло привести к AV ?
← →
brother © (2010-04-06 05:28) [16]> Принципиально спрошу
может не надо?
← →
Константин (2010-04-06 10:25) [17]Принципиально написал пример:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Contnrs;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TA = class(TObjectList)
public
FStrings: TStringList;
constructor Create(OwnsObjects: Boolean);
procedure Clear; override;
destructor Destroy; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TA }
procedure TA.Clear;
begin
inherited Clear;
FStrings.Clear;
end;
constructor TA.Create(OwnsObjects: Boolean);
begin
FStrings := TStringList.Create;
end;
destructor TA.Destroy;
begin
FStrings.Free;
inherited;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a: TA;
begin
a := TA.Create(True);
a.Add(a);
a.FStrings.Add("asdf");
a.Free;
end;
end.
Давайте уважаемы, расскажите мне про FStrings и влияние наименования этого поля на ошибку доступа?
← →
Сергей М. © (2010-04-06 10:40) [18]
public // <-- нашиша это поле делать публичным ?
FStrings: TStringList;
constructor TA.Create(OwnsObjects: Boolean);
begin
inheritred Create(OwnsObjects); // <-- грабли - в отсутствии инициализации объекта-предка
FStrings := TStringList.Create;
end;
← →
Константин (2010-04-06 10:58) [19]
> Сергей М. © (06.04.10 10:40) [18]
Это понятно, и дело не в этом. Пусть мне люди которые говорили о FStrings объяснят то что я спросил.
Потому что получается так, что я вот допустим написал public, и из меня делают лузера и всё такое, а сами же (не вы Сергей) несут полнейшую чушь.
> Для начала замени Strings на FStrings, например, так как
> Strings в предке может использоваться.
Терпеть не могу умников. Мы по-моему уже обсуждали с вами, Сергей, других людей, которые тут есть еще.
← →
Константин (2010-04-06 10:59) [20]думаю, тему вообще надо закрыть, во избежание дальнейшего бреда...
← →
Leonid Troyanovsky © (2010-04-06 11:01) [21]
> Константин (06.04.10 10:25) [17]
Inherited Destroy вызывает Clear,
а FStrings к тому моменту уже разрушен.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2010-04-06 11:03) [22]
> Константин (06.04.10 10:59) [20]
> думаю, тему вообще надо закрыть, во избежание дальнейшего
> бреда...
Ну, дык, кто ж мешает избегать.
--
Regards, LVT.
← →
Сергей М. © (2010-04-06 11:06) [23]
> Константин (06.04.10 10:58) [19]
> Это понятно, и дело не в этом
Как же не в этом, когда именно в этом ?)
Отсутствие вызова конструктора наследуемого класса как раз и приводит к описанным тобой выше граблям.
А публикование поля FStrings - этот источник потекциальных граблей.
← →
Константин (2010-04-06 11:19) [24]
> Сергей М. © (06.04.10 11:06) [23]
Согласен я просто в порыве страсти забыл дописать
inherited Create(OwnsObjects);
> Leonid Troyanovsky © (06.04.10 11:01) [21]
Верно. Но наименование поля тут непричём.
> Сергей М. © (06.04.10 11:06) [23]
> А публикование поля FStrings - этот источник потекциальных
> граблей.
Согласен, но у предка нету такого поля.
← →
Сергей М. © (2010-04-06 11:35) [25]
> Константин (06.04.10 11:19) [24]
> у предка нету такого поля
Сегодня нет, а завтра, в каком-то другом классе, найдется.
Поэтому тебе и говорят - привыкай общепринятому к порядку, минимизирующему риск наступить на подобные грабли.
Да и можешь ли ты вразумительно объяснить причину публиковангия тобой поля FStrings ?
Думаю что нет)
← →
Дмитрий Белькевич (2010-04-06 11:40) [26]
> Согласен, но у предка нету такого поля.
А при чём тут предок? Частные структуры класса должны скрываться внутри класса.
← →
Anatoly Podgoretsky © (2010-04-06 11:43) [27]> Сергей М. (06.04.2010 11:35:25) [25]
Может он не умеет работать со свойствами.
← →
Дмитрий Белькевич (2010-04-06 11:46) [28]
> А при чём тут предок?
Увидел.
Тем не менее:
> Частные структуры класса должны скрываться внутри класса.
← →
Константин (2010-04-06 11:47) [29]
> Да и можешь ли ты вразумительно объяснить причину публиковангия
> тобой поля FStrings ?
Публикования? Это того что я занес в секцию public? Если да, то я занёс так скажем по привычке того, что я запишу в обработчике кнопки строку, так как не хотел писать метод доступа для private поля. Думаю это можно понять и я думаю вы понимаете смысл моих слов и мыслей, раз уж вы мастер (ничего личного), так скажем. Да и я пример привёл с override Clear - это самое важно место я и хотел показать, поэтому и забыл написать inherited Create(OwnsObjects); и прочие недостатки и неточности.
← →
Дмитрий Белькевич (2010-04-06 11:50) [30]
> Может он не умеет работать со свойствами.
Судя по его коду, и свойство не нужно. Достаточно сделать метод типа AddEx (что бы с предком не пересекался, да).
a := TA.Create(True);
a.Add(a);
Зачем TA добавляет сам себя в контейнер? Не понял. Он сам себя не разрушит?
← →
Anatoly Podgoretsky © (2010-04-06 11:50) [31]> Константин (06.04.2010 11:47:29) [29]
метод доступа для private поля совсем не обязателен, посмотри тему по свойствам, особое внимание на модификторы
← →
Сергей М. © (2010-04-06 11:54) [32]
> думаю вы понимаете смысл моих слов и мыслей
Если бы понимал - не спрашивал бы)
Откуда ж мне знать, что причина публикования частного поля - всего лишь в "не хотел писать метод доступа ", но при этом ты вполне осознаешь чем это чревато ?)
Я по-твоему обязан телепатировать ?)
← →
Дмитрий Белькевич (2010-04-06 11:57) [33]
> и прочие недостатки и неточности.
Это не недостаток и не неточность. Это грубейшее нарушение принципов ООП.
> так как не хотел писать метод доступа для private поля.
Он пишется буквально за 2 секунды.
procedure Add(const s: string);
после - ctrl-shift-c.
Или, как Подгорецкий говорит, можно FStrings вытащить наружу через read-only свойство:
← →
Anatoly Podgoretsky © (2010-04-06 12:02) [34]> Дмитрий Белькевич (06.04.2010 11:57:33) [33]
Почему через ReadOnly можно и через ReadWrite - это уже по задаче и без всяких методов, хотя на запись метод напрашивается, что бы было надежно, без утечек и контролируемо.
Вообще чистое ООП не подразумевает доступность каких либо полей напрямую, только через методы (свойства)
← →
Константин (2010-04-06 12:08) [35]
> Дмитрий Белькевич (06.04.10 11:50) [30]
Вот хорошо, что вы заметили, я думал уже никто не напишет.
Вот вы все пишите пишите. Грубейшее нарушение ООП, методы доступа, и никто не написал "да, у TObjectList нету поля Strings, но ты там то хреново сделал, там ошибки грубейшие, ты не прав". Телепатируете? ))
Вообщем ребят, давайте жить дружно, как говорится. А критиковать все могут.
← →
Дмитрий Белькевич (2010-04-06 12:14) [36]
> Почему через ReadOnly можно и через ReadWrite - это уже
> по задаче и без всяких методов, хотя на запись метод напрашивается,
> что бы было надежно, без утечек и контролируемо.
ReadWrite в данном случае зачем может понадобится? Не могу сразу придумать.
← →
Дмитрий Белькевич (2010-04-06 12:17) [37]
> А критиковать все могут.
Ну ты с этим согласись, а там - дальше поедем ;) Будешь упорствовать в ереси - никто больше ничего не скажет ;)
← →
Дмитрий Белькевич (2010-04-06 12:24) [38]Есть хороший принцип - не всё сразу. Учись двигаться по шагам. Сказали - здесь - фигня. Правь фигню - выкладывай код - спрашивай дальше. Скорее всего еще что-то от форума получишь. На противодействие, боюсь, получишь только противодействие.
← →
Константин (2010-04-06 12:26) [39]
> Дмитрий Белькевич (06.04.10 12:17) [37]
Да без проблем, я против насилия и хочу чтобы на форумах процветали мир, благодать, взаимоуважение, взаимопонимание и общий вектор качественного решения проблем, наставления на путь истинный и т.п. Человеческое общение!
← →
Дмитрий Белькевич (2010-04-06 12:31) [40]
> Да без проблем, я против насилия и хочу чтобы на форумах
> процветали мир, благодать, взаимоуважение, взаимопонимание
> и общий вектор качественного решения проблем, наставления
> на путь истинный и т.п. Человеческое общение!
Тут недавно это плотно обсуждали. Всё, что тебе говорят - это уже после этой ветки. До этой ветки просто сразу в дворники отсылали ;)
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.058 c