Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.27;
Скачать: CL | DM;

Вниз

Адреса protected полей класса   Найти похожие ветки 

 
Verg ©   (2005-03-03 20:52) [0]

Может ли (должен ли иметь право) потомок получать или передавать вовне адрес(а) унаследованного protected члена? (Может и не только адрес ни и ссылку ( var, const, reference )).
Речь не идет о конкретном ЯВУ. Вообще, в принципе.... по идее...
Я считаю, что нет.
Он относится к разряду защищенных и изменять его не членам дерева наследования или даже давать такую возможность было бы нарушением этой защиты. Пустть сам потомок манипулирует зачением этого члена как угодно, но получать его адрес ( сам факт ) создает угрозу объявленной ( заявленной ) защите.


 
Anatoly Podgoretsky ©   (2005-03-03 21:04) [1]

По идеологии есть полные права на повышение статуса, вплоть до Published. Права делегированы наследнику.


 
Shaman_Naydak   (2005-03-03 21:15) [2]

если мы говорим про поля класса, то отдавать его для манипулирования вне класса-наследника вообще неправильно иделогически.
> Podgoretsky
Объясните плиз как вы собираетесь повысить видимость полю класса?


 
Anatoly Podgoretsky ©   (2005-03-03 21:16) [3]

Вообще то не подумал, может и нельзя :-(


 
vuk ©   (2005-03-03 21:25) [4]

Зато свойству видимость повысить можно.


 
Verg ©   (2005-03-03 21:25) [5]

Сам факт получения адреса (@ или & или передача в качестве var процедуру/метод класса не наследника), вообще в, в принципе, на чем должна занканичваться защита полей класса? Может она не должна заканчиваться, тогда сам факт получения адреса защищенного члена неправомерен.
Вот интересен этот, как кажется, идеологический вопрос, но я надеюсь в ближайшее время я смогу более конкретно сформулировать конкретику, всязи с появлением новой модели компилятора C++ от MSFT, которая заставила задуматься об этом вопросе.
Некоторые считают полноценныю защиту обявленную словом protected за глюк этого компилера...


 
wicked ©   (2005-03-03 21:35) [6]

afaik неправильно... но может быть использовано, как полезный трюк...

> (Может и не только адрес ни и ссылку ( var, const, reference
> )).

то есть, даже в функции RTL передавать ссылку нельзя?... через локальные переменные только?...
ср.
Val(<string>, fMyField, <err>);
и
Val(<string>, temp_var, <err>);
fMyField := temp_var;


 
vuk ©   (2005-03-03 21:38) [7]

Вообще говоря, все, что является protected, действительно отдается на откуп потомкам, и только от них зависит, что делать с добром, полученным в наследство. Можно наружу передавать, а можно и рыбу заворачивать. Тут уж все от разработчика зависит.


 
Verg ©   (2005-03-03 21:44) [8]

"Наследство" дано с условием protected, т.е. "только сын мой, и сын твоего сына, равно со своим отцом" сможет безраздельно влавствовать над "моим богатсвом". В то же время выписка "чеков на предьявителя" должна быть категорически запрещена по определнию (protected).
А иначе нахрен было писать protected?


 
Набережных С. ©   (2005-03-03 21:44) [9]

Имхо, у класса вообще не должно быть доступных извне полей.


 
vuk ©   (2005-03-03 21:54) [10]

>В то же время выписка "чеков на предьявителя" должна быть
>категорически запрещена по определнию (protected).
Только вот как при этом прикажете быть со всякими функциями-утилитами? Есть protected экземпляр какого-то класса и внешняя функция, которая что-то с ним делает. Получается, что функцию вызывать нельзя (ведь получается передача наружу адреса protected данных), а можно только продублировать код ее ручками в своем методе и только потом вызывать. Получаем типа новый подход к Code Reuse? :o)


 
Verg ©   (2005-03-03 21:57) [11]


> Набережных С. ©   (03.03.05 21:44) [9]


Пусть и так. Пусть доступ к ним идет только через методы этого класса.
Но допустимо ли (попробую на Дельфи выразить):

TMyClass = class
protected
 FSomeField : integer;
public
 function GetSomeFiled : PInteger;
end;

function TMyClass.GetSomeFiled : PInteger;
begin
 result := @FSomeField; // На мой взгляд - нонсенс, нарушение прав
end;

Т.е. public метод "игнорирует" правило protected ! На каком основании он делегирует право разпоряжаться значением protected поля "кому попало"?


 
Набережных С. ©   (2005-03-03 22:01) [12]


> vuk ©   (03.03.05 21:54) [10]

Честно говоря, что-то не уловил. Функция, не метод, я правильно понял? Ну есть функция, ну обращается она хоть даже и к приватным, ну и что? Функционал скрыт в ней, он не изменится, к собственно внутренним полям извне все-равно нет. Или что?


 
Verg ©   (2005-03-03 22:05) [13]


> Получается, что функцию вызывать нельзя (ведь получается
> передача наружу адреса protected данных), а можно только
> продублировать код ее ручками в своем методе и только потом
> вызывать.


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


 
vuk ©   (2005-03-03 22:06) [14]

to Набережных С. ©   (03.03.05 22:01) [12]:
Чтобы внешняя функция сделала что-то с экземпляром класса (да и любыми данными), необходимо передать ей адрес этих данных. Если операцию получения адреса для protected данных считать неправомерной, то передать что-то внешней функции не представляется возможным.


 
Набережных С. ©   (2005-03-03 22:07) [15]


> Verg ©   (03.03.05 21:57) [11]

Именно это и хотел сказать, что такое не допустимо. В идеале. В реале, к сожалению, иногда искушение пересиливает:(


 
Набережных С. ©   (2005-03-03 22:12) [16]


> vuk ©   (03.03.05 22:06) [14]

Ну и правильно. Если это дружественная функция, то она имеет все права. А остальным внутри класса делать нечего. Да и без дружественных лучше бы обходиться.


 
Игорь Шевченко ©   (2005-03-03 22:16) [17]

Verg ©   (03.03.05 21:57) [11]

Невозможно защититься от злокозненного программиста.

Точно такая же возможность допустима в С++, с, на мой взгляд, более строгим контролем видимости. Например, если для класс объявлен friend, то он может отдавать наружу private-поля класса (по ссылке на них, например), не противореча грамматике языка.
Грамматика разрабатывалась не для того, чтобы запретить всевозможные варианты обхода видимости :)

С уважением,


 
vuk ©   (2005-03-03 22:16) [18]

to Набережных С. ©   (03.03.05 22:12) [16]:
>Если это дружественная функция, то она имеет все права.
Эт как? Функция утилита должна быть дружественной всем классам, которые хотят ее использовать?


 
Набережных С. ©   (2005-03-03 22:22) [19]


> vuk ©   (03.03.05 22:16) [18]

А в чем проблема? Либо она должно оперировать только публичными данными.


 
Verg ©   (2005-03-03 22:22) [20]


> Игорь Шевченко ©   (03.03.05 22:16) [17]


> Грамматика разрабатывалась не для того, чтобы запретить
> всевозможные варианты обхода видимости :)


Все верно. Но ведь именно грамматика. Если написал, что protected, то и нечего "наружу концы раздавать" обходными путями.
Никто ж за язык не тянул.
Для какого нафига написал protected? От кого protected?
Это как бесконечные const в c++, от которых по-началу стреляешься, а потом начинешь отдавать должное некоей мудрости.


 
DiamondShark ©   (2005-03-03 22:24) [21]


> Я считаю, что нет.

Тогда не сметь использовать конструкции вида
SetLength(FPrivateField,...
Read(FPrivateField,...
и т.п.


 
vuk ©   (2005-03-03 22:25) [22]

>А в чем проблема?
Проблема в еще необъявленных классах.


 
У   (2005-03-03 22:25) [23]

ИМХО, уровень protected не предназначен для полей.
А в основном для функций и свойств.


 
Набережных С. ©   (2005-03-03 22:29) [24]


> vuk ©   (03.03.05 22:25) [22]

Нет, не понимаю. Пример можешь привести?


 
DiamondShark ©   (2005-03-03 22:32) [25]


> Сам факт получения адреса (@ или & или передача в качестве
> var процедуру/метод класса не наследника)

Если мы говорим "не о конкретном ЯВУ. Вообще, в принципе.... по идее...", то получение адреса, и передача по ссылке -- это принципиально разные вещи.


 
Verg ©   (2005-03-03 22:32) [26]


> DiamondShark ©   (03.03.05 22:24) [21]
>
> > Я считаю, что нет.
>
> Тогда не сметь использовать конструкции вида
> SetLength(FPrivateField,...
> Read(FPrivateField,...
> и т.п.


Точно, совершенно верно. Класс при обявлении защищенных членов должен совершенно четко обозначить права своих непотомков (путем объявления списка или модуля/класса) или вообще внеклассовых структур, имеющих, тем не менее, полный доступ к объвляемым защищенным своим полям. И только им можно передавать ссылки или указатели на свои поля.


 
Verg ©   (2005-03-03 22:34) [27]


> DiamondShark ©   (03.03.05 22:32) [25]
>
> > Сам факт получения адреса (@ или & или передача в качестве
>
> > var процедуру/метод класса не наследника)
>
> Если мы говорим "не о конкретном ЯВУ. Вообще, в принципе....
> по идее...", то получение адреса, и передача по ссылке --
> это принципиально разные вещи.


Не вижу принципиальной разницы.


 
Verg ©   (2005-03-03 22:36) [28]

Но вот так вот дозволять "вникуда отстреливать" ссылки на свои "непростые" поля.... на мой взгляд неправильно.


 
Anatoly Podgoretsky ©   (2005-03-03 22:39) [29]

Мы нарвались на проблемы этики отдельно взятого программистов, права у него есть, а вот делать так не этично.


 
DiamondShark ©   (2005-03-03 22:39) [30]


> Класс при обявлении защищенных членов должен совершенно
> четко обозначить права своих непотомков

А зачем? Чтоб "в гамаке и на лыжах"?
Класс прекрасно осведомлён о своих приватных членах, и вправе делать с ними что угодно.
Зачем придумывать механизмы, которые не будут работать?
Ну хорошо. Запретим мы внешним процедурам доступ по ссылке к приватным полям. А толку? Оператор присваивания мы тоже будем запрещать или отдельно декларировать? Кто запретит вместо
read(FPrivateField);
написать
read(LocalVar);
FPrivateField := LocalVar;
?
Никто. А что мы выиграем в идеологии, кроме лишнего гемора и усложнения компилятора? Ничего.


 
vuk ©   (2005-03-03 22:39) [31]

to Набережных С. ©   (03.03.05 22:29) [24]

>Нет, не понимаю. Пример можешь привести?

procedure UtilityProc(Instance: TSomeClass);
begin
 //что-то делаем с Instance
end;

TSomeOtherClass = class
...
protected
 FSomeInstance: TSomeClass;
 procedure SomeMethod;
end;

procedure TSomeOtherClass.SomeMethod;
begin
...
 UtilityProc(FSomeInstance);
...
end;

потом, где-то в другом месте, через пару лет

TMyClass = class(TSomeOtherClass)
 procedure MyMethod;
end;

procedure TMyClass.MyMethod;
begin
...
 UtilityProc(FSomeInstance);
...
end;

Если нельзя получать адрес protected полей, то вызов UtilityProc неправомочен (туда экземпляр передается). Если же UtilityProc каким-то образом должна являться дружественной к классу, который ее вызывает, то она обязана быть дружественной к еще необъявленным классам. Вот отсюда и вопрос. Эт как?


 
vuk ©   (2005-03-03 22:41) [32]

А вообще если идти до конца, то все, что не public, нужно делать private, а наследование запретить как класс. Чтобы неповадно было. :o)


 
DiamondShark ©   (2005-03-03 22:43) [33]


> Verg ©   (03.03.05 22:34) [27]
>
> Не вижу принципиальной разницы.

Адрес -- понятие машинное, implementation dependent.
Ссылка -- чисто концептуальное. Оно даже абстракнее, чем, скажем, такая тривиальная вещь, как "целое число".


 
DiamondShark ©   (2005-03-03 22:46) [34]

Да, кстати, о protected полях.
Protected -- это интерфейс разработчика.
Т.е. предполагается, что он опубликован и документирован.
Так что наследник с protected имеет полное право обращаться так же, как и со своими private.


 
DiamondShark ©   (2005-03-03 22:47) [35]


> vuk ©   (03.03.05 22:41) [32]

Вообще-то, да.
Мне в этом плане Zonnon нравится.


 
Verg ©   (2005-03-03 22:50) [36]


> DiamondShark ©   (03.03.05 22:39) [30]
>
> > Класс при обявлении защищенных членов должен совершенно
>
> > четко обозначить права своих непотомков
>
> А зачем? Чтоб "в гамаке и на лыжах"?
> Класс прекрасно осведомлён о своих приватных членах, и вправе
> делать с ними что угодно.
> Зачем придумывать механизмы, которые не будут работать?


Да. Нахрен ж тогда protected вообще. Да и вообще разграничение public/protected/public ?
Да и const, который по-моему только с D6 опомнились и запретили модифицировать.

Но уж если "назвались", то извиняйте - не ты назвал protected (речь о наследниках) - не тебе лезть к этим полям с такими "попытками несанкц. доступа".


 
Anatoly Podgoretsky ©   (2005-03-03 22:58) [37]

Если в языке есть работа с указателями, взятие адреса, то ни о какой защите от программиста говорить не приходится.


 
DiamondShark ©   (2005-03-03 23:01) [38]


> Нахрен ж тогда protected вообще

Интерфейс разработчика.

Если запрещается межмодульное наследование (а в компонентно-ориентированных средах это должно быть сделано), то нахрен не нужен.


 
vuk ©   (2005-03-03 23:07) [39]

to DiamondShark ©   (03.03.05 22:47) [35]
Наследование, вроде как, там не отменяли... :o)


 
DiamondShark ©   (2005-03-03 23:16) [40]


> vuk ©   (03.03.05 23:07) [39]

Наследуются только интерфейсы.
Для code reuse пожалуйте использовать агрегацию.

http://zonnon.ethz.ch/papers/Zonnon_Language_Report_v02r02_2_y041101.pdf



Страницы: 1 2 вся ветка

Текущий архив: 2005.03.27;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.036 c
3-1109672491
lehich
2005-03-01 13:21
2005.03.27
получение текущего времени SQL сервера


3-1108961050
Ярослав
2005-02-21 07:44
2005.03.27
Глобальные переменные в FireBird


1-1110904405
tazik
2005-03-15 19:33
2005.03.27
Как заглушить солиста в мр3


8-1102796840
Iks
2004-12-11 23:27
2005.03.27
Draw on Desktop


8-1103031593
Пассажир бронепоезда
2004-12-14 16:39
2005.03.27
MediaPlayer + AVI