Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с областью видимости переменных 
V
    Опции темы
rodnover
Дата 29.8.2011, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



Код

unit Unit2;

interface

type
  TA = class
  protected
    function func: string; virtual;
  end;

implementation

function TA.func: string;
begin
  Result := 'Test';
end;

end.



Код

unit Unit3;

interface

uses
  Unit2;

type
  TB = class(TA)
  protected
    Owner: TA;
    function func: string; override;
  public
    constructor Create(Own: TA);
  end;

implementation

{ TB }

constructor TB.Create(Own: TA);
begin
  Self.Owner := Own;
end;

function TB.func: string;
begin
  Result := Owner.func + ', Test2';    // [DCC Error] Unit3.pas(28): E2362 Cannot access protected symbol TA.func
end;

end.



По идее, класс TB наследуется от TA, следовательно он должен иметь доступ к protected методам родителя. Почему в таком случае delphi запрещает это делать (и с чем это связан этот запрет) и как можно обойти это ограничение? 
PM MAIL   Вверх
Frees
Дата 29.8.2011, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 9
Всего: 54



Код

Result := inherited func + ', Test2';



--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
rodnover
Дата 29.8.2011, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



Frees, не, не то. Мне именно поля Owner надо вызвать, а не Self. Я хочу декоратор сделать, но не хочу объявлять некоторые protected методы как public.

Это сообщение отредактировал(а) rodnover - 29.8.2011, 12:12
PM MAIL   Вверх
Snowy
Дата 29.8.2011, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Ты можешь обратиться к своей protected функции. но не к protected функции другого объекта, даже, если технически он ссылается на тебя.
PM MAIL   Вверх
rodnover
Дата 29.8.2011, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



Придется открывать. Плохо.
PM MAIL   Вверх
sCreator
Дата 29.8.2011, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.8.2009
Где: Московская област ь

Репутация: 2
Всего: 5



Сделай маленький хак  smile 
Код

unit Unit3;

interface
uses
  Unit2;
type
  TAHack = class(TA);

  TB = class(TA)
  protected
    Owner: TA;
    function func: string; override;
  public
    constructor Create(Own: TA);
  end;
implementation
{ TB }
constructor TB.Create(Own: TA);
begin
  Self.Owner := Own;
end;
function TB.func: string;
begin
  Result := TAHack(Owner).func + ', Test2';    // [DCC Error] Unit3.pas(28): E2362 Cannot access protected symbol TA.func
end;

end.

PM   Вверх
superVad
Дата 29.8.2011, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 735
Регистрация: 6.4.2006
Где: Черкассы, Украина

Репутация: 4
Всего: 15



sCreator, 
Код

constructor TB.Create;
begin
  Self.Owner := TA.Create;
end;

?

Это сообщение отредактировал(а) superVad - 29.8.2011, 20:56
PM MAIL   Вверх
sCreator
Дата 29.8.2011, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.8.2009
Где: Московская област ь

Репутация: 2
Всего: 5



Цитата(superVad @  29.8.2011,  18:54 Найти цитируемый пост)
?
ответ: ваша цитата не верна - у меня такого кода нет

PM   Вверх
rodnover
Дата 29.8.2011, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



sCreator, завтра попробую. Крутой хак!! Идея отличная, конечно. Спасибо!
PM MAIL   Вверх
superVad
Дата 29.8.2011, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 735
Регистрация: 6.4.2006
Где: Черкассы, Украина

Репутация: 4
Всего: 15



Цитата(sCreator @  29.8.2011,  17:08 Найти цитируемый пост)
ответ: ваша цитата не верна - у меня такого кода нет

удалил лишние теги smile

Я про то - может создавать объект родитель, а не передавать?
PM MAIL   Вверх
rodnover
Дата 30.8.2011, 07:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



Цитата(superVad @  30.8.2011,  00:57 Найти цитируемый пост)
Я про то - может создавать объект родитель, а не передавать?

Это всё равно не позволит в protected метод доступ получить.
PM MAIL   Вверх
Frees
Дата 30.8.2011, 07:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 9
Всего: 54



Цитата(rodnover @  29.8.2011,  16:25 Найти цитируемый пост)
Придется открывать. Плохо.


Это значит ты гдето ошибся в проектировании классов.

и это тоже признак ошибок проектирования
Цитата(sCreator @  29.8.2011,  20:17 Найти цитируемый пост)
TAHack(Owner).func



Это сообщение отредактировал(а) Frees - 30.8.2011, 07:48


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
rodnover
Дата 30.8.2011, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



А как тогда сделать в Делфи 2 дружественных класса не помещая их в одном модуле?
PM MAIL   Вверх
Frees
Дата 30.8.2011, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 9
Всего: 54



Цитата(rodnover @  30.8.2011,  11:38 Найти цитируемый пост)
А как тогда сделать в Делфи 2 дружественных класса не помещая их в одном модуле?

спроектировать по другому, что бы такого желания не возникало - единственно правильный способ


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
rodnover
Дата 30.8.2011, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



Соглашусь на половину (чуть больше половины). Чем мне нравятся дружественные классы в С++, что класс сам определяет какие классы будут ему дружественными, в отличии от хака предложенного выше.
Это верный но способ, не не факт, что единственно правильный. ;) Всё-таки иногда считаю, что группа классов должна работать как единое целое (с точки зрения экономии строчек кода и повышения производительности).

Это сообщение отредактировал(а) rodnover - 30.8.2011, 12:44
PM MAIL   Вверх
Frees
Дата 30.8.2011, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 9
Всего: 54



Почитай GoF


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
sCreator
Дата 30.8.2011, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.8.2009
Где: Московская област ь

Репутация: 2
Всего: 5



Цитата(Frees @  30.8.2011,  09:53 Найти цитируемый пост)
спроектировать по другому, что бы такого желания не возникало - единственно правильный способ 

Проектирование не нужно в зависимость от языка программирования. Он может только внести какие то ограничения.
А если проектирование загнать в жесткие рамки шаблонов и правил - это будет уже не творчество, штамповка.

Класс TAHack только делает доступными защещенные методы в другом модуле ( в данном случае модуле наследника ) и он намного менее неправелен, чем возможность вызывать приватные методы в других классах одного модуля.


Кстати описание класса TAHack лучше поместить в раздел implementation.



PM   Вверх
Frees
Дата 30.8.2011, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 9
Всего: 54



Цитата(sCreator @  30.8.2011,  20:41 Найти цитируемый пост)
Проектирование не нужно в зависимость от языка программирования. 

писатель на коленках, мелких поделок?

Цитата(sCreator @  30.8.2011,  20:41 Найти цитируемый пост)
Он может только внести какие то ограничения.А если проектирование загнать в жесткие рамки шаблонов и правил - это будет уже не творчество, штамповка.

а программирование это и есть штамповка по готовым шаблонам, творчество - это как объединяются эти шаблоны.



--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
superVad
Дата 30.8.2011, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 735
Регистрация: 6.4.2006
Где: Черкассы, Украина

Репутация: 4
Всего: 15



sCreator, т.е. это бок ОбжектПаскаля? В других языках есть такая возможность?
Ну - что нельзя делать дружественные классы - или как оно там называется.
PM MAIL   Вверх
sCreator
Дата 30.8.2011, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.8.2009
Где: Московская област ь

Репутация: 2
Всего: 5



Не буду сейчас про дружественные. 
Напомню: В последних делфинах уже введен доп модификатор видимости sealed.
В C# (навскидку):
 кроме 3 основных делфийских еще комбинация с internal ( т.е. внутри сборуи ) ( а private только внутри класса, но там в классе можно объявлять вложенные классы ).
Плюс к этому частичные классы, методы расширения ...

Про бок я бы не стал так сразу.

Каждый язык начинается с концепций и развивается.
Delphi в свое время можно сказать из учебно-тренировочного языка сделали передовую среду разработки.
С++ ( ИМХО ) слишком заверчен. НО если учесть, что тогда все ручками, а он позволял двумя символами несколько строк другого языка изобразить...

Кстати а почему бы не сказать, что классы описанные в одном модуле и являются дружественными?

И почему нельзя расширить эту возможность на несколько взаимосвязанных модулей "моим хаком", если разработчик знает что делает.
Кстати при использовании "моего хака" и разнесением потомков в разные модули модель работы получается более логичной. Приватные члены хак не открывает.
И ( если не ошибаюсь ) этот хак я подсмотрел в одном из исходников Delphi.
PM   Вверх
CodeMonkey
Дата 30.8.2011, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



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

Поскольку в Delphi эту функцию тесной связи классов выполняет модуль, то дружественные классы тут просто не нужны. Соответственно, в Delphi дружественные классы - это классы одного модуля.

Откуда следует, что вопрос "как тогда сделать в Делфи 2 дружественных класса не помещая их в одном модуле?" равносилен "как тогда сделать в C++ 2 дружественных класса не делая их дружественными?"

Ответ: никак (на оба вопроса).

Это сообщение отредактировал(а) CodeMonkey - 31.8.2011, 15:38


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
rodnover
Дата 31.8.2011, 07:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



Но это же большой минус, если кучу классов (пусть, даже 2) лепить в одном модуле. Модуль разрастается, ориентироваться в нём становится одно удовольствие (ирония).

 
Еще один вопрос скорее по ООП в общем, если в приведённом вначале коде заменить class TB так:

Код

unit Unit3;
interface
uses
  Unit2;
type
  TB = class(TA)
  protected
    Owner: TB;
    function func: string; override;
  public
    constructor Create(Own: TB);
  end;
implementation
{ TB }
constructor TB.Create(Own: TB);
begin
  Self.Owner := Own;
end;
function TB.func: string;
begin
  Result := Owner.func + ', Test2';  
end;
end.


Код компилируется (что логично - модуль один). Для эксперимента написал подобный код в С++ - тоже компиляция. Тогда получается что в данном случае требование

Цитата(Snowy @  29.8.2011,  17:09 Найти цитируемый пост)
Ты можешь обратиться к своей protected функции. но не к protected функции другого объекта, даже, если технически он ссылается на тебя. 


не выполняется. Почему тогда такая двойственность? Логичнее же исключить такую двойственность и быть так: либо нет допуска ко всем другим объектам (даже такого же типа) кроме public, либо ко всем объектам являющимися таким же классом или классом родителя должен быть доступ на уровне protected.

Это сообщение отредактировал(а) rodnover - 31.8.2011, 07:05
PM MAIL   Вверх
sCreator
Дата 31.8.2011, 07:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.8.2009
Где: Московская област ь

Репутация: 2
Всего: 5



Цитата(CodeMonkey @  30.8.2011,  21:33 Найти цитируемый пост)
"как тогда сделать в C# 2 дружественных класса не делая их дружественными?"

Я бы даже сказал: ]"как тогда сделать в C# 2 дружественных класса?" - ответ никак.
Дружественные классы, это C++ и модульности в нем гораздо больше чем в C#. 
В С++ каждый *.cpp компилируется отдельно, так же как в Delphi *.pas. А потом все линкуется.
Я бы сказал: необходимость более тесной связи классов была решена в C++ и Delphi разными способами. 

PM   Вверх
sCreator
Дата 31.8.2011, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.8.2009
Где: Московская област ь

Репутация: 2
Всего: 5



Цитата(rodnover @  31.8.2011,  08:04 Найти цитируемый пост)
Ты можешь обратиться к своей protected функции. но не к protected функции другого объекта, даже, если технически он ссылается на тебя. 
не выполняется.


А теперь добавь к процитированной фразе еще две:
С++:
1. можно обратиться к закрытому члену объекта дружественного класса
2. класс является дружественным сам себе

Delphi:
1. можно обратиться к закрытому члену объекта класс которого описан в том же модуле ( т.е. классы определенные в одном модуле дружественные)
2. описания любых двух объектов одного класса находятся в одном модуле (класс является дружественным сам себе)

Вот твой пример и сработал.
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0743 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.