Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.06.2017, 15:29   #11
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

property это просто более удобный синтаксис для GetXXX/SetXXX функций.

Я ж показал какие: можно сделать его неизменяемым извне.
Ну или вообще без поля что-то вычислять.
Или делать что-то еще при присваивании.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 30.06.2017, 15:32   #12
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

К паблик есть доступ из кода. А свойство можно сделать только для чтения, защитив его от ошибочного изменения из вне
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 30.06.2017, 15:37   #13
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Инкапсуляция. Вы когда пишете property можете сделать проверку по входу. Ваш объект всегда будет иметь гарантированно-рабочее состояние.
Плюс параллельность и асинхронность. Можно организовать синхронизацию по коду.
Но в целом это не такие большие преимущества.
Обязательно для COM. Для плагинов это то что доктор прописал.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 30.06.2017, 15:42   #14
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Я ж показал какие
Какие - это я понял. Я не понял, чем
Код:
setMaxID(12)
лучше, чем
Код:
MaxID:=12
Цитата:
Сообщение от Alex11223 Посмотреть сообщение
можно сделать его неизменяемым извне.
Хм. А это интересно. Учту на будущее. Но в данном случае мне это не подойдёт: у меня есть список из наследников TNomObject и список из других наследников TNomObject. В каждом из вторых наследников есть подсписок из некоторых из первых TNomObject.
Условно говоря, есть список отрезков и список трасс. Каждая трасса состоит из нескольких отрезков.
Когда я создаю отрезок, я добавляю его по очереди сначала в объект трассы а потом в список отрезков (надеюсь, добавляется один и тот же и при изменении в списке отрезков изменится и в трассе, не проверял пока). Но списки разные, а ID у отрезка должно быть одно, назначаться списком отрезков. А у меня получается, что оно сначала назначается одним списком, а потом другим меняется (если там не разные копии создаются).
Ship_1 вне форума Ответить с цитированием
Старый 30.06.2017, 15:47   #15
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Вы когда пишете property можете сделать проверку по входу.
Уже читал эту фразу, когда разбирался с классами, но так её и не понял. Как это? (в кодовом виде примера) Добавить условие проверки в Set? Или что-то другое?
Ship_1 вне форума Ответить с цитированием
Старый 30.06.2017, 15:47   #16
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Так вы ж ID хотели постоянным сделать.

Ну и для наследников можно protected вместо private если надо.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 30.06.2017, 15:57   #17
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Alex11223 Ну да, постоянным, пока есть этот отрезок.
Хм. А если сделать его неменяемым извне, то тогда и проблемы с изменением при двойном добавлении не будет? Но тогда и присваивать его не в Add надо?
Ship_1 вне форума Ответить с цитированием
Старый 30.06.2017, 16:02   #18
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

"двойном добавлении" это как?
Присваивать в конструкторе.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 30.06.2017, 16:25   #19
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Ну я ж написал: у меня есть список отрезков и список трасс. Каждая трасса содержит список отрезков, в который входят некоторые из тех, которые в списке отрезков. Что-то типа такого:
[отрезок 1, отрезок 2, отрезок 3, отрезок 4, отрезок 5, отрезок 6, отрезок 7, отрезок 8, отрезок 9]
Трасса 1: [отрезок 2, отрезок 5, отрезок 7]
Трасса 2: [отрезок 1, отрезок 5, отрезок 7]
Трасса 1: [отрезок 3, отрезок 4, отрезок 6]
Отрезок я сначала добавляю в список отрезков, а потом в трассу. Вот и получается двойное добавление.

Боюсь я конструкторов пока... Не совсем понимаю чего там можно делать, чего нельзя делать и про что надо не забыть... Но придётся попробовать.

Последний раз редактировалось Ship_1; 30.06.2017 в 16:27.
Ship_1 вне форума Ответить с цитированием
Старый 03.07.2017, 10:29   #20
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Воспользовавшись советами сделал из ID property и запихнул его присвоение в Create, изменил Add в списке, убрав Create объекта в него. Но теперь при добавлении-создании объекта программа просто прекращает работу с сообщением от винды:
Цитата:
"возникшая проблема привела к прекращению работы программы"
Как это должно быть сделано, чтобы этой ошибки не было?
Код:
type
  TNomObject = class
  public
    ID: integer;
    constructor Create(NewID: integer);
  end;
  TNomList = class(TObjectList)
  private
//    Function FindEmptyID: integer;
    function GetItem(Index: Integer): TNomObject;
    procedure SetItem(Index: Integer; const Value: TNomObject);
    function GetNextMaxID: Integer;
    function getMaxID: Integer;
    procedure setMaxID(const Value: Integer);
    property MaxID: Integer read getMaxID write setMaxID;
  public
    function FindID(NomID: Integer): Integer;
    function Add(AObject: TNomObject; CreateNew: boolean = true): Integer;
    property Items[Index: Integer]: TNomObject read GetItem write SetItem; default;
  end;
  ...
  TSegm = class(TNomObject)
    ...
  end;
  TSegms = class(TNomList)
  private
    function GetItem(Index: Integer): TSegm;
    procedure SetItem(Index: Integer; const Value: TSegm);
  published
  public
    property Items[Index: Integer]: TSegm read GetItem write SetItem; default;
  end;
  TTrace = class(TNomObject)
    ...
    Segments: TSegms;
  end;
  TTraces = class(TNomList)
  private
    function GetItem(Index: Integer): TTrace;
    procedure SetItem(Index: Integer; const Value: TTrace);
  published
  public
    property Items[Index: Integer]: TTrace read GetItem write SetItem; default;
  end;
  TLevel = class(TNomObject)
    ...
    LevelTraces: TTraces;
  end;
  TLevels = class(TNomList)
  private
    function GetItem(Index: Integer): TLevel;
    procedure SetItem(Index: Integer; const Value: TLevel);
  published
  public
    property Items[Index: Integer]: TLevel read GetItem write SetItem; default;
  end;
  ...
  TForm1 = class(TForm)
    ...
    procedure N1Click(Sender: TObject);
	...
  private
    { Private declarations }
  public
    { Public declarations }
	...
    Levels: TLevels;
    Segms: TSegms;
	...
  end;


constructor TNomObject.Create(NewID: integer);
begin
  ID := NewID;
end;

function TNomList.GetNextMaxID: Integer;
begin
  Result:=getMaxID+1;
end;

function TNomList.getMaxID: Integer;
begin
  Result:=MaxID;
end;

procedure TNomList.setMaxID(const Value: Integer);
begin
  MaxID:=Value;
end;

function TNomList.GetItem(Index: Integer): TNomObject;
begin
  Result := TNomObject(inherited GetItem(Index));
end;

procedure TNomList.SetItem(Index: Integer; const Value: TNomObject);
begin
  inherited SetItem(Index, Value);
end;

function TNomList.FindID(NomID: Integer): Integer;
begin
  For Result:=0 to Count-1 do
    If Items[Result].ID = NomID then
      exit;
  Result:=-1;
end;

//Function TNomList.FindEmptyID: integer;
//begin
//  Result:=0;
//  If count>1 then While FindID(Result)>=0 do inc(Result);
//  ShowMessage(IntToStr(Result));
//end;

function TNomList.Add(AObject: TNomObject; CreateNew: boolean = true): Integer;
begin
  if CreateNew then
  begin
    AObject := TNomObject.Create(getMaxID);
    SetMaxID(GetNextMaxID);
  end;
  Result := inherited Add(AObject);
//  Items[Result].ID:=FindEmptyID;
end;


procedure TForm1.N1Click(Sender: TObject);
var
  NewLevel:TLevel;
begin
  ...
  If Form2.ShowModal=mrOK then
  begin
    ShowMessage('Adding');
    Levels.Add(NewLevel);
    ShowMessage('Added');
	...
  end;
end;

Последний раз редактировалось Ship_1; 03.07.2017 в 10:31.
Ship_1 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
список полиморфных объектов denrubun Общие вопросы C/C++ 4 17.11.2013 14:38
Добавление своих объектов в Добавление своих объектов в двунаправленный кольцевой список voidmain C# (си шарп) 3 21.03.2013 13:08
динамический список объектов tim47 Помощь студентам 0 16.05.2012 16:17
проблема с идентификаторами itwaswritten Помощь студентам 0 08.05.2010 20:34
Список полиморфных объектов kaarb Помощь студентам 0 20.06.2009 11:24