Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Вопрос о свойствах (property)


Автор: Ryn 6.9.2006, 15:05
у меня есть запись, она используется в классе:
Код

TTest = record
  fValue_1 : integer;
  fValue_2 : integer;
end;
...

CTest = class
  private
    fTest : TTest;
  public
    Property pTest : TTest Read fTest Write fTest;
end;


но при обращении к полям fValue_1 или fValue_2:

Код

...
var
  sTest : CTest;
begin
  sTest := CTest.Create;
  sTest.pTest.fValue_1 := 1;
  sTest.pTest.fValue_1 := 2;
end;


 делфи пишет - "Left side cannot be assigned to".

как это устранить ? только я не хочу писать функции присваивания в классе для этих полей.

Автор: Romikgy 6.9.2006, 15:09
а на кой те этот гемор? нельзя эту запись в publiс засунуть?

Автор: Alexeis 6.9.2006, 15:15
Цитата(Romikgy @  6.9.2006,  15:09 Найти цитируемый пост)
нельзя эту запись в publiс засунуть? 

Не надо учить плохому! Это и есть реализация инкапсуляции - базового принципа ООП.

Ryn, Проидется писать через промежуточную переменную типа TTest

Автор: Romikgy 6.9.2006, 15:31
Цитата(alexeis1 @  6.9.2006,  14:15 Найти цитируемый пост)
Не надо учить плохому!

а че здесь плохого ? зачем вообще придумали private?
Цитата(Ryn @  6.9.2006,  14:05 Найти цитируемый пост)
 private
    fTest : TTest;
  public
    Property pTest : TTest Read fTest Write fTest;

а здесь от него толку никакого, или я не прав?

Автор: Alexeis 6.9.2006, 15:37
Цитата(Romikgy @  6.9.2006,  15:31 Найти цитируемый пост)
а здесь от него толку никакого, или я не прав? 

Пока что нет но в будущем такой класс легко наращивать или безопасно изменять. Просто вместо переменной будет указана функция которая помимо присваивания сделает может еще десяток операций, т.о. интерфес сохранится а функциональность возрастет. Так что модификации подвергнется только код класса, а не код всех проектов использующих этот класс.

Автор: Yanis 6.9.2006, 15:41
Код
var
  c: CTest;
  t: TTest;
begin
  c.pTest := t;
end;

Автор: Snowy 6.9.2006, 15:44
Romikgy, есть такая штука - инкапсуляция.
Сейчас ты поднимаешь вопрос о том, зачем она нужна...
Об этом расскажет любая книжка по ООП.

Теперь к вопросу. Почему.
Потому что запись не ссылочный тип и не может полноценно использоваться, как проперти.
Какой тут выход.
1. Использовать не запись, а объект.
Код

  TTest = class
  public
    fValue_1 : integer;
    fValue_2 : integer;
  end;

  CTest = class
    private
      fTest : TTest;
    public
      Property pTest : TTest Read fTest Write TTest;
      constructor Create;
      destructor Destroy; override;
  end;

implementation

constructor CTest.Create;
begin
  fTest := TTest.Create;
  fTest.fValue_1 := 0; fTest.fValue_2 := 0;
end;

destructor CTest.Destroy;
begin
  fTest.Free;
  inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sTest : CTest;
begin
  sTest := CTest.Create;
  sTest.pTest.fValue_1 := 1;
  sTest.pTest.fValue_1 := 2;
end;


2. Использовать указатель на запись.
Код

  PTest = ^TTest;
  TTest = record
    fValue_1 : integer;
    fValue_2 : integer;
  end;

  CTest = class
    private
      fTest : PTest;
    public
      Property pTest : PTest Read fTest Write fTest;
      constructor Create;
      destructor Destroy; override;
  end;

implementation

constructor CTest.Create;
begin
  New(fTest);
  fTest.fValue_1 := 0; fTest.fValue_2 := 0;
end;

destructor CTest.Destroy;
begin
  Dispose(fTest);
  inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sTest : CTest;
begin
  sTest := CTest.Create;
  sTest.pTest.fValue_1 := 1;
  sTest.pTest.fValue_1 := 2;
end;


Добавлено @ 15:46 
Ну, и как указал Yanis, в текущем состоянии запись можно назначать только целиком.

Автор: Ryn 6.9.2006, 15:49
понял, всем спасибо. буду как публис использовать, так проще вроде _)

Автор: Romikgy 6.9.2006, 16:00
Цитата(alexeis1 @  6.9.2006,  14:37 Найти цитируемый пост)
Просто вместо переменной будет указана функция которая помимо присваивания сделает может еще десяток операций,

знаю , просто 
Цитата(Ryn @  6.9.2006,  14:05 Найти цитируемый пост)
только я не хочу писать функции присваивания в классе для этих полей. 


Цитата(Snowy @  6.9.2006,  14:44 Найти цитируемый пост)
есть такая штука - инкапсуляция.

знаю , только мало вижу смысл ее здесь применения (имено так как был описан класс!)
Цитата(Snowy @  6.9.2006,  14:44 Найти цитируемый пост)
Сейчас ты поднимаешь вопрос о том, зачем она нужна...

нет не поднимаю

Автор: Snowy 6.9.2006, 16:05
Цитата(Ryn @  6.9.2006,  15:49 Найти цитируемый пост)
буду как публис использовать, так проще вроде
Так конечно проще. Не самое грамотное решение, но кода меньше.

Цитата(Romikgy @  6.9.2006,  16:00 Найти цитируемый пост)
только мало вижу смысл ее здесь применения
Никогда не знаешь, когда понадобится.
Сейчас кажется - нафиг не нужно, а потом "блин, надо было".
Всё таки грамотный красивый стиль подразумевает инкапсулировать, а не выпячивать на публику.

Автор: Romikgy 6.9.2006, 16:48
Еще раз повторюсь , 
Цитата(Snowy @  6.9.2006,  15:05 Найти цитируемый пост)
а не выпячивать на публику. 

я все говорил применительно к выставленому коду! 
ЗЫ ну объясни мне смысл прятать переменую в приват , если в паблике ты обращаешься к ней на прямую?

Автор: Ryn 6.9.2006, 16:53
Romikgy,
просто столкнулся с такой проблемой и решил спросить. ведь со стандартными типами и классами работает, а с записью нет.

Автор: Snowy 6.9.2006, 17:41
Цитата(Romikgy @  6.9.2006,  16:48 Найти цитируемый пост)
ну объясни мне смысл прятать переменую в приват , если в паблике ты обращаешься к ней на прямую?
В том и смысл, чтобы не было прямого обращения, а обращение шло через инкапсуляцию.
В идеале вообще не должно быть прямого доступа, а только инкапсуляция.
Но дельфи позволяет писать на разных уровнях.
Да можно и делать прямой доступ.
Просто так не принято в ООП.
Посмотри исходняки VCL и другиз стандартных классов.
Нигде нет прямого обращения - всё сделано через инкапсуляцию.
Я не заставляю, всего лишь указываю, что грамотно инкапсулировать.

Автор: Romikgy 6.9.2006, 18:39
Цитата(Snowy @  6.9.2006,  16:41 Найти цитируемый пост)
Просто так не принято в ООП.

дык я об этом и говорю!
Цитата(Snowy @  6.9.2006,  16:41 Найти цитируемый пост)
В идеале вообще не должно быть прямого доступа

и про это
Цитата(Snowy @  6.9.2006,  16:41 Найти цитируемый пост)
Я не заставляю, всего лишь указываю, что грамотно инкапсулировать.

должна быть не спорю, но имхо она должна быть еще и разумной!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)