Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.08.2022, 18:13
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию Указатель на объект

Правильно ли я понимаю что переменная типа TObject или его наследников, это всегда указатель, про который компилятору (ну или кому там) не нужно объяснять что это указатель ('^', '@' - вот это вот все) . И сам объект существует (если конечно он был создан) независимо от того сколько указателей на него существует.
Ну т.е. в практическом плане:
Код:
  TPart = class (TObject)
  private
    FName: string;
    FRemainder: Word;
  public
    property Name: string read FName write FName;
    property Remainder: Word read FRemainder write FRemainder;
  end;

  TPartsArray = array of TPart;

  TProduct = class(TObject)
  private
    FName: string;
    FPartList: TPartsArray ;
  public
    property Name: string read FName write FName;
    property PartList: TPartList read FPartList write FPartList;
  end;
могу ли я создавая кучу экземпляров TProduct, в конструкторе или в каком методе, сделать так (массив ведь это же тоже указатель, на первый элемент)
Код:
constructor TProduct.Create(AParts: TPartsArray);
begin
  .....  
  FPartList[someIndex]:= AParts[anotherIndex];
end;
т.е. такое обращение будет обращением к одним и тем же данным в памяти
Код:
MyProduct1: TProduct;
AllParts: TPartsArray;
...
MyProduct1.PartList[i].Name;
AllParts[j].Name;
Ответить с цитированием
  #2  
Старый 28.08.2022, 05:02
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Не совсем понятне вопрос, но да, любой экземпляр класса - это указатель.
С массивами там немного другая тема. Да, это тоже указатель, но он обрабатывается компилятором тодельным образом.
А вот каждый элемент массива объектом - тоже обычный указательна объект.

Не уверен, что второй класс в первом примере будет работать так, как ты задумал. В смысле property PartList объявленная как массив. Как я уже приводил пример, там лучше сделать индексированное св-во с геттером и сеттером. Хотя если будешь следить за своим кодом, то может и будет работать...
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Помидоркин (29.08.2022)
  #3  
Старый 31.08.2022, 07:23
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Не совсем понятен вопрос...
Основное что я пытаюсь для себя уяснить: существует ли объект независимо от наличия и количества указателей на него.
Создание объекта это выделение памяти под него и все его поля, присвоение nil указателю не удаляет объект из памяти.
Поля типов не являющихся классами (число, строка, boolen) удаляются автоматом при вызове деструктора объекта.
Объявление переменной типа TSomeClass не создает новый объект (не выделяет под него память), а присвоение:
Код:
CurrenPart:=  AllParts[0];
означает что CurrenPart и AllParts[0] это два указателя на одну и ту-же область памяти.

Цитата:
Сообщение от lmikle
..лучше сделать индексированное св-во с геттером и сеттером
Вот кстати да, это же вот про это?
Код:
    property Parts[Index: Word]: TPart read GetParts write SetParts;
    property Products[Index: Byte]: TProduct read GetProducts write SetProducts;
    property Tasks[Index: Word]: TTask read GetTasks write SetTasks;
Сначала так и сделал, а в других классах, чисто на автомате, объявил свойство типа массив, а потом сам удивлялся что оно работает. И возник вопрос: в чем разница? Если я правильно понимаю, имя (переменная) массива это указатель на первый элемент и при обращении к массиву Array[Index] фактически это будет адрес первого элемента + индекс. Собственно геттер\сеттер это и делают.
Код:
function TMyJSONdb.GetTasks(Index: Word): TTask;
  begin Result:= FTasks[Index]; end;

procedure TMyJSONdb.SetTasks(Index: Word; const Value: TTask);
  begin FTasks[Index]:= Value; end;

Последний раз редактировалось Помидоркин, 31.08.2022 в 07:32.
Ответить с цитированием
  #4  
Старый 31.08.2022, 09:00
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию

Чёта я запутался, собственно что я пытаюсь сделать: есть класс и массив его экземпляров
Код:
  TPart = class (TObject)
  private
    FName: string;
    FNeed: Word;
    FDone: Word;
  public
    property Name: string read FName write FName;
    property Need: Word read FNeed write FNeed;
    property Done: Word read FDone write FDone;
  end;

  TPartsArray = array of TPart;
       .............
AllParts: TPartsArray;
есть класс у которого есть свой массив (пока не понятно чего, это собственно и пытаюсь понять)
Код:
  TProduct = class(TObject)
  private
    FName: string;
    function GetPart(const Index: Byte): TProductPart;
    procedure SetPart(const Index: Byte; const Value: TProductPart);
  public
    property Name: string read FName write FName;
    property Part[Index]: TProductPart read GetPart write SetPart;  //<<<????
  end;
       .............
Product: TProduct
нужно чтобы TProductPart указывал на TPart, но при этом содержал другие поля. Первое что приходит в голову:
Код:
  TProductPart = class(TObject)
  private
    FItem: TPart;
    FCount: Byte;
  public
    property Item: TPart read FItem write FItem;
    property Count: Byte read FCount write FCount; //к количесву элементов отношения не имеет
  end;
выглядит не очень, Product.Part[i].Item, по-моему наследование и полиморфизм не для этого придумывали.
Вроде как нужно наследовать
Код:
  TProductPart = class(TPart)
  private
    FCount: Byte;
  public
    property Count: Byte read FCount write FCount;
  end;
непонятно что дальше, допустим
Код:
(Produdct.Part[i] as TPart):= AllPart[k]; //ну или типа того
ну т.е. если я не создаю Produdct.Part[i], то где будет храниться Сount? А если создаю, то выделяется память и все вот это становится бессмысленным.

upd. Пришел в голову вот такой вариант:
Код:
  TProductPart = class(TObject)
  private
    FPart: TPart;
    FCount: Byte;
    function GetName: string; //SetName - по аналогии;
  public
    property Name: string read GetName write SetName;
      // и все остальное так же
    property Count: Byte read FCount write FCount; //к количесву элементов отношения не имеет
  end;
    .....
function TProductPart.GetName: string
begin
  Result:= FPart.Name;
end;
Вроде должно работать, но вот это вот - дублировать каждое свойство с прописыванием для каждого Get\Set. Есть у меня ощущение что все это можно как-то проще и в Delphi давно уже придумано.

Последний раз редактировалось Помидоркин, 31.08.2022 в 11:12.
Ответить с цитированием
  #5  
Старый 31.08.2022, 18:00
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ой бяда, бяда...

Ты что, пытаешься сделать связь многие-ко-многим в виде объектов?
Тогда уж бери какую-нибудь локальную БД и пользуй ее.

ЗЫ. Вообще не понимаю задачу. Что ты пытаешься сделать вообще...
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Помидоркин (01.09.2022)
  #6  
Старый 01.09.2022, 08:13
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
сделать связь многие-ко-многим в виде объектов

Вообще не понимаю задачу. Что ты пытаешься сделать вообще...
Именно это и пытаюсь
БД в первую очередь и рассматривались, в самом начале я вообще пытался в Access, но со времен Office 97 его настолько улучшили что... печальная тема.
Пытался с БД в Delphi, но по старой доброй традиции материалы по теме имеют вид: "одно яблоко плюс одно яблоко будет два яблока, теперь вы знаете математику и для закрепления полученных знаний вот вам квадратное уравнение".
Впрочем не это главное, в общем по совокупности многих факторов решил делать сам, с нуля. А бонусом хочу проникнуться духом ООП, в который, как выясняется, я нифига не умею, ну почти.

Последний раз редактировалось Помидоркин, 01.09.2022 в 10:18.
Ответить с цитированием
  #7  
Старый 01.09.2022, 21:07
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А зачем тебе access, пользуй просто Jet, он то не меняется (это просто движок access'а). Или возьми FireBird Embedded. Можно еще наколупать с помощью ClientDataSet или какого-нить TDBF, но там ссылочную целостность придется отслеживать самому.

Ну то, что ты с ООП не очень дружишь, это я и так понял.
Даже не знаю что тебе посоветовать.
Как вариант, делать честно, как в БД. Т.е. в объектах, предсталяющих собой связи, хранить именно индексы объектов, а не сами объекты и, соответсвенно. иметь методы поиска самих объектов в соотв. списках. Да, и хранить именно индексы (ID) объектов, а не индексы элементов массивов (ну, если запретить удаление, то можно и индексы массивов).

Кстати, наследование в твоей задаче ппактически и не нужно. Тут тебе скорее требуется инкапсуляция. Полюс шаблон типа Фасад...
Ответить с цитированием
  #8  
Старый 02.09.2022, 07:14
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Как вариант, делать честно, как в БД. Т.е. в объектах, предсталяющих собой связи, хранить именно индексы объектов, а не сами объекты и, соответсвенно. иметь методы поиска самих объектов в соотв. списках. Да, и хранить именно индексы (ID) объектов, а не индексы элементов массивов (ну, если запретить удаление, то можно и индексы массивов).
Тут то и кроется та совокупность факторов - у меня структура данных очень простая и меняться не будет. Да и элементов не много, поэтому обращаюсь по индексу (в массиве) только к TPart, все остальное нахожу простым перебором.
Цитата:
Сообщение от lmikle
Кстати, наследование в твоей задаче практически и не нужно. Тут тебе скорее требуется инкапсуляция.
Ну т.е. как в моем последнем варианте?
Код:
  TProductPart = class(TObject)
  private
    FPart: TPart;
    .....
  end;
Цитата:
Сообщение от lmikle
... шаблон типа Фасад...
А вот отсюда можно по-подробнее?
Ответить с цитированием
  #9  
Старый 02.09.2022, 20:53
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Да какая бы система не была. Вот смотри, самая простая система.
Есть спавочник деталей. Есть документ, ну пусть будет наряд. И есть позиции наряда. Таким образом у тебя уже будет 3 бизнес объекта. И это еще без многие-ко-многим, только минимум. При этом в позициях документа тебе надо держать не копии элементов справочника, а ссылки на него.

ЗЫ. Да, Фасад тут все-таки не нужен, хотя, если заморочиться можно сделать и единый интерфейс.

ЗЗЫ. Это у тебя реальная задача или просто для себя что-то ваяешь. Если реальная - делай на БД (если нужно, где-то у меня был пример с Embedded Firebird, еще на D7 написанный через IBX, могу попробовать поискать).
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Помидоркин (03.09.2022)
  #10  
Старый 04.09.2022, 08:09
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию

Ну как сказать: реальная задача, которую ваяю просто для себя, ну т.е. пользоваться буду только я, точнее уже пользуюсь, по большому счету основная функциональность уже реализована. Так что разбираться с БД, переделывать все с нуля, как то.. Осталось немного мелочей, а то в некоторых случаях приходится в .json ручками лазить, а это не есть хорошо.
Очень бегло глянул про "фасад", если я правильно понял, он у меня в некоторой степени реализован. Есть объект TjsonBD который и содержит в себе все объекты, в нем же реализованы все методы для манипуляций с объектами.
И да, еще раз спасибо, из ответов я почерпнул для себя много полезного.
Ответить с цитированием
  #11  
Старый 06.09.2022, 19:47
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

и все же я рекомендую смотреть в сторону БД для подобных задач.
Просто со временем объем данных будет расти и начнуться проблемы с быстродействием и аппаратными требованиями. Плюс в БД ты получаешь "бесплатно" много полезных функций, например контроль ссылочной целостности, использование индексов для ускорения поиска данных и многое другое.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Помидоркин (09.09.2022)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:28.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter