Лена |
Отправлено: 03.08.2005, 15:16 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Вопросы тем, кто программирует много лет. Просто интересен опыт знатоков.
Приходилось ли вам использовать в своих проектах следующее:
1. Наследование классов через private, т.е. полностью закрытое наследование.
2. Множественное наследование.
3. Дружественные классы.
4. Вложенные классы.
|
|
Doga |
Отправлено: 03.08.2005, 15:29 |
|
Мастер участка
Группа: Участник
Сообщений: 575
|
1. Через private наследовать практически нет смысла, разве что через protected.
2., 3., 4. — постоянно.
|
|
vvoid |
Отправлено: 03.08.2005, 15:49 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
Хм....хороший вопрос для дискуссии, надеюсь так и будет ;-)
По порядку ;-)
1. Наследование классов через private, т.е. полностью закрытое наследование. Реально вижу возникновение такой необходимости, хотя к моему стыду не разрабатывал достаточно сложные проэкты где был бы необхоим настолькообъектно-ориентированный подход.
2. Множественное наследование. Достаточно неприятная и муторная штука. По-норамльному спроектированная система в 90% может обойтись без этого. Средства языка С++, к сожалению :-(, не позволяют нормально разруливать некоторые узкие места.
3. Дружественные классы. Скорее распорка, созданная (опять же в ~90%) для внесения в поправок в плохо спроэктированную систему.
(использования этого, ИМХО, не делает программисту чести)
4. Вложенные классы. Если речь идёт о таком отношении между классами, как "Использование", то это вполне красивое решение — гараздо лучшее чем множественное наследование, я так считаю.
Отредактировано vvoid — 03/08/2005, 15:52
|
|
Doga |
Отправлено: 03.08.2005, 17:22 |
|
Мастер участка
Группа: Участник
Сообщений: 575
|
2vvoid
Допустим имеется 2 класса, которые предоставляют пользователю только часть своих свойств, но при этом необходимо обеспечить взаимный доступ к закрытым данным этих классов. Помоему, только дружественные классы имеют такую возможность. Если уж этим "грешат" и STL, и MFC, и VCL, то нам, простым смертным, можно сказать сам Бог велел
Множественное наследование, согласен, не рациональное решение. Пользуюсь этим только в "безвыходных" ситуациях.
|
|
vvoid |
Отправлено: 03.08.2005, 17:31 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
QUOTE (Doga @ 03/08/2005, 17:22) | необходимо обеспечить взаимный доступ к закрытым данным этих классов |
А почему эти данные закрыты? И почему нет метода, позволяющего к ним доступиться?
Не говоря о том, что самовольное изменение значений private членов класса может привести к нарушению стабильного состояния класса (если мне не изменяет память, это называется инвариантностью)
PS да и если чесно хорошее проэктирование MFC, STL и VCL вызывает у меня сомнения... но чётких доказательств у меня нет. Так что-то читал, на что-то натыкался, говорили, так сказать, старшие товарищи
Отредактировано vvoid — 03/08/2005, 17:34
|
|
Doga |
Отправлено: 03.08.2005, 17:40 |
|
Мастер участка
Группа: Участник
Сообщений: 575
|
А данные закрыты для того беспокойного программиста, котрый и будет употреблять эти классы, дабы не вводить его лишний раз во искушение нарушить стабильную работу вышеупомянутых классов.
QUOTE |
чесно хорошее проэктирование MFC, STL и VCL вызывает у меня сомнения...
|
Ну, тогда, не знаю...
По Вашему, если дер...мо завернуть в фантик, так оно от этого слаще станет?
Пардон за "ненормативную" лексику.
Отредактировано Doga — 03/08/2005, 18:08
|
|
vvoid |
Отправлено: 03.08.2005, 17:47 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
Закрытие данных — это не метод. 100пудво! Для того чтобы не нарушать стабильного состояния класса используются методы, которые по-грубому можно назвать SetXxx и GetXxx, в которых и выполняются разные проверки, типа а можно ли сейчас такое вымутить.
QUOTE | По Вашему, если дер...мо завернуть в фантик, так оно от этого слаще станет? |
Так в том то и дело, что когда спроэктировано дерьмово и приходится заворачивать в фантик, чтоб хоть кто-то это юзал. А в случае с MFC, VCL, STL "хоть кто-то" — это мягко сказано ;-)
А вообще, конечно, VCL и STL ещё более-менне путёвые штуки, а вот к MFC у меня прямо какая то личная неприязнь.
Отредактировано vvoid — 04/08/2005, 11:34
|
|
Doga |
Отправлено: 03.08.2005, 17:55 |
|
Мастер участка
Группа: Участник
Сообщений: 575
|
Прошу прощения, я имел ввиду не только закрытые данные, но и закрытые методы.
А в какой секции объявляются те самые SetXxx и GetXxx ?
А сколько других закрытых переменных и методов ... ну в любом VCL-классе?
Отредактировано Doga — 03/08/2005, 18:03
|
|
vvoid |
Отправлено: 03.08.2005, 18:05 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
QUOTE | А в какой секции объявляются те самые SetXxx и GetXxx ? |
На сколько я помню в vcl-евских классах эти методы лепятся в __published. Я могу и ошибаться.
В своих классах, если я рассматриваю возможность предоставления пользователю классов возможность читать/менять значения каких-либо private переменных, то объявляю сеты и геты как public
QUOTE | А сколько других закрытых переменных и методов ... ну в лубом VCL-классе? |
Ну так для того они и сделаны, чтобы не другой программер не побил идеологию созданной системы. До что там идеологию, побить можно и саму систему. Ну вот посудите, вы ведь не хачите h-ники чужих библиотек, ну или, по крайней мере, понимаете, что это хак, причём грязный.
Отредактировано vvoid — 03/08/2005, 18:06
|
|
Doga |
Отправлено: 03.08.2005, 18:28 |
|
Мастер участка
Группа: Участник
Сообщений: 575
|
Вообще то, я, мягко говоря, сомневаюсь что они "лепятся в __published"
QUOTE |
чтобы другой программер не побил идеологию созданной системы |
Вот тут Вы попали в точку!
P.S. А в чужих библиотеках ковыряться приходилось — исправлял али усовершенствовал чего...
Отредактировано Doga — 03/08/2005, 18:36
|
|
vvoid |
Отправлено: 03.08.2005, 18:51 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
QUOTE | Вообще то, я, мягко говоря, сомневаюсь что они "лепятся в __published" |
Точно! Извиняюсь!
Я тут открыл годичный исходник своего первого и пока единственного компонента и действительно обнаружил, что SetXxx и GetXxx там объявлены в private, но у билдера здесь есть новая распорка: __property, которая и даёт возможнасть читать и изметянь значения свойств компонента. Но тут получается, что некуда деваться и приходится принимать то, что предлагает инструмент.
QUOTE | P.S. А в чужих библиотеках ковыряться приходилось — исправлял али усовершенствовал чего... |
Ну если только для себя, то конечно можно поэкспериментировать. Да и вообщем то не только для себя тоже можно, но тут уже смотря лицензию Но всё равно, хачить h-ники того же Builder-а или Visual-а я избегаю всеми средствами.
А по поводу другого программера, то наверное стоит сказать, что и самому можно побить свою собственную же систему. Мало ли, нужно например через некоторое время вернуться к уже вроде бы написаному проэкту, ну и неупомнил какую-то деталь, а потом неделю в глубоком долбаге выискиваешь, где же эта чёртова бага. ;-)
|
|
** Admin |
Отправлено: 03.08.2005, 20:05 |
|
Не зарегистрирован
|
Знатоком не являюсь и программирую не очень много лет,
но никогда не приходилось в проектах пользоваться пп 1-5
Как то без этого всего проще, либо не доводилось
залазить в такие сложные проекты где бы это понадобилось.
|
|
Георгий |
Отправлено: 03.08.2005, 20:15 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
1. нет. на эту тему можно долго рассуждать, но практического применения этому не нашёл.
2. ещё как. особенно виртуальное
3. пару раз. не могу сказать, что это понравилось, но сберегло кучу времени т.к. пришлось бы перепроектировать структуру классов со всеми вытекающими последствиями.
4. да. иногда некоторым методам на вход надо передать нечто экзотическое. вот эту экзотику и описывал как вложенный класс. |
|
Asher |
Отправлено: 10.08.2005, 11:08 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Привет.
2,3,4 постоянно.
Теперь по поводу п1.
class B : private A;
Поскольку А является для B закрытым, то неявно преобразовывать B* в А* могут только члены и друзья B. И они же могут обращаться к открытым и защищенным членам A.
Иногда это здорово поднимает надежность.
Даже от самого себя, не говоря уже о сторонних программистах.
|
|
Aractan |
Отправлено: 10.08.2005, 14:04 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 22
|
1. нет
2. интерфейсы (особенно в СОМ)
3. случалось, скорее как заплатки. Ален И. Голуб ( в книге Веревка достаточной длинны что бы выстрелить себе в ногу...) рекомендует даже в этом случе обращаться к закрытым полям через специальные закрытые функции члены. Еще встречал пример использования friend в "Паттерны проетирования. Приемы ООП" паттерн Memento, в принципе оправдано.
4. Вложенные классы — постоянно. |
|
olegenty |
Отправлено: 10.08.2005, 14:27 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
к сожалению в последнее время в повседневной работе ООП не использую. все приложения пишутся для работы с БД и срочно. поэтому чистое процедурное программирование + обработка событий типа OnClick + обработка собственногенерируемых событий. подробно займусь ООП, когда наконец найду время написать для будущих проектов среднее звено для работы с БД.
|
|
Aractan |
Отправлено: 11.08.2005, 15:01 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 22
|
пример использования 3.
http://www.research.att.com/~bs/bs_faq2.ht...l#no-derivation |
|
Георгий |
Отправлено: 11.08.2005, 22:05 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
ёё! сегодня использовал №1 и очень понравилось!
смотрите какая идея:
класс A — какой-нибудь алгоритм (например крутой парсер XML)
класс B — клиентский интерфейс для класса A (например когда парсер натыкается на нестандартный элемент XML то от вызывает по этому интерфейсу метод "появился новый элемент" и передаёт тому текст этого элемента)
класс C — какая-нибудь прикладная штука, которую очень удобно реализовать используя A (например класс хранящий часть своих полей в XML документе), но при этом никому не позволять использовать себя через интерфейс B.
тогда пишем:CODE | class C: private B
{
public:
void load(void)
{
A a;
a.process( *this );
};
}; | и никакая зараза не сможет сделатьCODE | C c;
A a;
a.process( c ); | |
|