На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (4) [1] 2 3 ... Последняя » все  ( Перейти к последнему сообщению )  
> Свойство-массив. Как правильно написать метод Free?
    Для хранения динамических массивов, как свойств класса написал такой класс TIntegerValues64:
    ExpandedWrap disabled
      type
          TInt64_1DArray = array of Int64;


    ExpandedWrap disabled
        
      TIntegerValues64 = class
        private
          fArray: TInt64_1DArray;
          function GetCount(): Integer;
          procedure SetCount(const Value: Integer);
          function GetArray(Index: Integer): Int64;
          procedure SetArray(Index: Integer; Value: Int64);
        public
          property Elements[Index: Integer]: Int64 read GetArray write SetArray; default;
          property Count: Integer read GetCount write SetCount;
          procedure Add(const aValue: Int64);
          procedure Destroy;
          procedure Free;
        end;


    Два вопроса:

    1) Как правильно написать методы Create, Destroy и Free?
    2) Не изобрел ли я велосипед? Это, ведь, очень похоже на TStringList, только про int64. Неужели нет в Delphi готового класса?

    Листинг метода Add:
    ExpandedWrap disabled
      procedure TIntegerValues.Add(const aValue: integer);
      begin
        SetLength(fArray, Length(fArray)+1 );
        FArray [Length(fArray)-1] := aValue;
      end;
    Сообщение отредактировано: ttiger -
      Free вообще писать не нужно.
      Destroy - не просто процедура, а destructor

      Конструктор и деструктор нужны, если требуется какая-то инициализация и финализация.

      >SetLength(fArray, Length(fArray)+1 );
      Так делать невыгодно - затраты памяти и времени будут велики. Стоит при необходимости увеличивать размер сразу вдвое или по крайней мере на значительно количество элементов.

      Вообще смысла в этом классе пока немного. Просто массив позволяет делать все то же самое, никаких особых удобств класс не добавляет.
      Если есть дополнительные соображения, расскажи.
        Для очистки динамического массива используется процедура Finalize.
          Цитата MBo @
          Destroy - не просто процедура, а destructor


          Да еще и виртуальный, так что override написать не забыть.
          ExpandedWrap disabled
            destructor Destroy; override;


          А Free уже написан в TObject.
            Цитата
            Вообще смысла в этом классе пока немного. Просто массив позволяет делать все то же самое

            Просто массив не может быть свойством, только полем. Если сделать его свойством, то не будет поэлементного доступа к его элементам.

            Цитата
            Destroy - не просто процедура, а destructor

            Мне стыдно :wall:

            Переделал:
            ExpandedWrap disabled
              TIntegerValues64 = class
                private
                  fArray: TInt64_1DArray;
                  function GetCount(): Integer;
                  procedure SetCount(const Value: Integer);
                  function GetArray(Index: Integer): Int64;
                  procedure SetArray(Index: Integer; Value: Int64);
                public
                  property Elements[Index: Integer]: Int64 read GetArray write SetArray; default;
                  property Count: Integer read GetCount write SetCount;
                  procedure Add(const aValue: Int64);
                  destructor Destroy; override;
                  //procedure Free; _DELETED FROM IMPLEMENTATION
                end;


            ExpandedWrap disabled
              implementation
              destructor TIntegerValues64 .Destroy;
              begin
                Finalize(fArray);
                inherited destroy;
              end;

            Проблема
            при вызове метода Free не выполняется деструктор моего объекта и указателю на объект не присваивается nill
              Цитата ttiger @
              Finalize(fArray);


              Не нужно, динамический массив финализируется при уничтожении объекта автоматически. А следовательно, можешь вообще деструктор не перекрывать, так как у тебя там только inherited.

              Цитата ttiger @
              при вызове метода Free не выполняется деструктор моего объекта


              Не может быть. Или ты нам чего-то недоговариваешь, или твой вывод неверный.

              Цитата ttiger @
              и указателю на объект не присваивается nill


              И не должен.
                >Просто массив не может быть свойством, только полем. Если сделать его свойством, то не будет поэлементного доступа к его элементам

                класс TIntegerValues64 в таком виде не несет полезной нагрузки.
                Если нужно индексированное свойство типа Int64 в каком-то действительно полезном классе, то и делай приватное поле - массив, индексированное свойство, геттер и сеттер. Создавать новую сущность я особого смысла не вижу.
                  Цитата
                  и делай приватное поле - массив, индексированное свойство, геттер и сеттер. Создавать новую сущность я особого смысла не вижу.

                  В классе, где используются эти свойства, таких две штуки публичных и три приватных.
                  Пять раз писать сеттер и пять раз геттер, прибавляя к ним процедуру добавления в конец - это вообще, нормально? А если одна ошибка п китайском коде? Распечатывать модуль и ВСЕ перечитывать?

                  Добавлено
                  Цитата --Ins-- @

                  Цитата (ttiger @ Сегодня, 11:34)
                  и указателю на объект не присваивается nill


                  И не должен.


                  Упс... У меня логика в методе следующая: в одном из свойств хранятся результаты подсчетов, притом они простои терируются. Перед тем, как повторно запускать подсчитывающий метод я "освобождаю" и снова создаю объект желаю таким образом очистить существующий, если есть и создать новый. Без явных доп. проверок.
                    >Пять раз писать сеттер и пять раз геттер, прибавляя к ним процедуру добавления в конец - это вообще, нормально
                    ОК, разумно.
                    На больше подробностей пока раскрутить не удалось 8-)
                      Главный вопрос был в том, не изобрел ли я велосипед.
                      Хотелось удобства добавления в конец массива как в StringList. Раз все молчат, значит, не изобрел. Уже хорошо, а то месяц мучаюсь этим вопросом.

                      Навероное, мне нужен метод FreeAndNill. Как его правильно написать для моего класса?
                        Вообще-то это процедура такая, FreeAndNil:

                        ExpandedWrap disabled
                          var
                            Obj: TSomeClass;
                           
                          ...
                            
                            Obj := TSomeClass.Create;
                           
                          ...
                           
                            FreeAndNil(Obj); // рекомендуется использовать везде, где это возможно, вместо Obj.Free;
                          Цитата CodeMonkey @
                          // рекомендуется использовать везде, где это возможно, вместо Obj.Free;


                          Странная рекомендация, если рассматривать ее не в контексте задачи а глобально. ;)

                          Цитата ttiger @
                          Навероное, мне нужен метод FreeAndNill. Как его правильно написать для моего класса?


                          Такого метода быть не может в принципе. Объект не может изменить Self так, чтобы эти изменения сказались снаружи вызова. К тому же, объект один, а ссылок на него может быть масса. Объект о них не знает ничего. Как он может их обнулить? Не путай сам объект и переменную, которая хранит на него ссылку.
                            Цитата ttiger @
                            Главный вопрос был в том, не изобрел ли я велосипед.

                            До D2009 - точно нет. В D2009 вместо самописного списка можно использовать TList<Int64>.

                            Цитата --Ins-- @
                            Странная рекомендация

                            Эээ.. чем?
                              Цитата CodeMonkey @
                              Эээ.. чем?


                              Ну, ты пишешь что рекомендуется использовать везде, а я этого не понимаю. Поясни :)
                                Ну причина проста - нет никаких доводов так не делать :) Зато есть доводы против использования Free (ниже).

                                Можно возразить, что, к примеру, это не всегда строго необходимо - как, например, при удалении локальных переменных. Однако как раз к такому аргументу есть следующие возражения:
                                1). Локальную переменную могут потом сделать глобальной или частично-глобальной. FreeAndNil защитит нас от double-free. Просто Free - нет.
                                2). Очень большое количество кода получается использованием copy-paste. Если стоит Free, то, скопировав код в другое место (где у переменной другая область видимости) мы можем получить проблемы. С FreeAndNil таких проблем нет.
                                3). Единообразие стиля. Удобно, когда везде написано FreeAndNil вместо помеси Free/FreeAndNil. И сам не запутаешься, когда что ставить ("ааа, здесь надо FreeAndNil или можно просто Free?!!").
                                4). Экономия одного нескольких байт и одного лишнего вызова процедуры (т.е. если заменить FreeAndNil обратно на Free) не является аргументом в современных приложениях.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0546 ]   [ 16 queries used ]   [ Generated: 5.12.22, 22:21 GMT ]