Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Концепция "Pointer to Implementation" |
Автор: EvilsInterrupt 19.1.2010, 01:38 | ||||
Вероятно все сталкивались с методикой pointer to impl, пример приведу тут: содержимое инклуда stack.h:
содержимое файла-реализация stack.cpp:
Это куски из примера ). В чем тут прикол, а то что заказчик лишен возможности видеть хоть какую-либо реализацию!!! Даже структура скрыта в файле-реализации. В случае private части класса, все логично и понятно! А что делать если это касается protected части базового класса ? Ведь потомок захочет вдруг воспользоваться тем что в protected части, а оно если следовать методике p-to-impl скрыто! Как быть ? Открывать ? Тогда : 1) заказчик больше получит информацию о строении либы 2) при изменении хоть чего-то в реализации, это еще одна перекомпиляция проекта, а так сделал интерфейс и меняй себе реализацию скольо хочешь! Как быть с protected частью базового, чтобы было доступно потомкам его и при этом скрыто от заказчика библиотеки классов ? ) |
Автор: kemiisto 19.1.2010, 11:07 | ||||||
+1 Только таки простой АТД. ;-)
Он ты как захотел. ![]()
Тут ведь в чём дело. С точки зрения современного ОО проектирования в вершине иерархии классов должен стоять либо интерфейс, либо абстрактный класс. Строго говоря, в Це++ нет ни того, ни другого. ![]() Ну и дальше там будет неувязочки
А всё почему? Прально! ![]() ![]() |
Автор: baldina 19.1.2010, 13:18 | ||||||||
EvilsInterrupt, обобщая сказанное mes и kemiisto: можно впихнуть невпихуемое и совместить pimpl с абстракцией. но они будут на разных уровнях иерархии. Например, вверху иерархии абстрактный стек:
клиентский код видит и использует только то, что ему положено:
реализация произвольна, например стандартный вектор
ЗЫ: если где нить инстанциировать шаблон, оно даже возможно заработает ![]() типа
|
Автор: EvilsInterrupt 19.1.2010, 19:23 |
И тем не менее, то что я привел называется Pimpl, вот по этому паттерну http://habrahabr.ru/blogs/qt_software/76248/ или http://www.insidecpp.ru/patterns/pimpl_idiom/ . В том что я привел в хидере объявляется указатель на структуру, которая всего-лишь объявлена, но определена в файле реализации! Это вполне удовлетворяет идее паттерна! Почему собственно возникла такая ситуация ? 1) Дело в том, что пользователя должно заботить только то что в паблик части, он это хотел, он это получил! 2) Проект может быть связан с системами компьютерной безопасности, зачем пользователю показаывать лишний раз детали, которые его абсолютно не касаются? 3) Если хидер описан умело, то не изменяя его, а только файлы реализации, то можно не боятся, что придется весь проект перекомпиливать ! 4) В среде разработке, когда пишешь код с применением code complition в комбобоксе также показывается и приват и протектед часть, нафига она мне пользователю класса нужна ? С private часть все понятно, но с protected тоже не мешало бы скрыть от юзера, как это сделать ? |
Автор: zim22 19.1.2010, 19:33 | ||||
мда... kemiisto вроде всё сказал уже:
|
Автор: baldina 19.1.2010, 19:46 | ||
Если заказчик будет наследовать классам либы, то ему, возможно, понадобится дополнительно знание о её строении. Тут все ок. Если заказчик НЕ будет наследовать классам либы, то protected данные в классах, видимых заказчику, вообще не нужны. |
Автор: mes 19.1.2010, 19:58 | ||||||
ну вот цитата из Вашей статьи :
можете показать где такое в Вашем примере ? ![]()
удовлетворяет - не значит достаточно ![]() Ну а по теме: все зависит от Ваших условий - сформулируйте их для себя.. что позволено клиенту и до какой степени и это будет ответом на вопрос какую из идеологий (или какой диалект идиологии) выбрать для Вашего случая. |
Автор: EvilsInterrupt 19.1.2010, 20:33 | ||
Вот и я о том, но возьмем к примеру ситуацию : 0) животное - базовый класс 1.1) Тигр от животного 1.2) Собака от животного Казалось бы заказчик заказывал только два животных - тигра и собаку, ну мало ли че, вдруг у него такая компьютерная игра не хитрая. Также требовал реализации того чтобы каждое животное умело прыгать, кусаться и лапу поднимать! А программист взял в базовом в защищенной(протектед) части определил - Раскрыть пасть, подвинуть голову, сомкнуть пасть, а в потомках тигре и собаке их реализовал. Казалось бы чего такого? Обычная задачка, но ! Это же надо писать в декларации классса в протектед части, а заказчик этот инклуд будет подключать для того чтобы можно было заюзать lib файл. Но скажите, на кой икс ему эти протектед части нужны ? Он и порождаться то не хочет. Как быть-то программеру ? Как спрятать защищенные методы вынесенные в базовый? Может их тупо убрать и кинуть в потомки?! Однако это не следование ООП-мысли !!! ;) |
Автор: zim22 19.1.2010, 21:00 |
ООП-мысль - это что? кстати, наследование нарушает инкапсуляцию. (GoF) |
Автор: mes 20.1.2010, 00:23 | ||
1. Не делать защищенные методы в классах не предназначенных для наследования 2. Не давать пользователю, то что ему не нужно 3. Не искать прямых путей - обходной может быть короче. Итого пользователю нужно : 1. интерфейс животного -> абстрактный класс с открытыми методами. 2. Два наследника этого -> два класса реализующих этот интерфейс с отсутсtвием лишних деталей. Разработчик реализует : 1. Описание ползовательских классов (include/animals.h) 2. Набор функций/ классов реализующих общее и индивидуальное поведение (source/animals_detail.h) 3. Связь пользовательских классов с функциональностью (source/animals.cpp) ![]() |
Автор: bsa 20.1.2010, 12:20 |
EvilsInterrupt, как вариант можно сделать два класса-обертки, конструкторы/деструкторы которых будут создавать/уничтожать реализацию, которая, в свою очередь, может быть какой угодно (хоть все методы виртуальные и открытые). Вот в этом случае и будет настоящий PIMPL - класс "тигр" будет содержать только указатель на класс TigerImpl, реализация которого будет исключительно внутри библиотеки, и доступные методы. ![]() |
Автор: baldina 20.1.2010, 12:40 | ||
EvilsInterrupt,
Вы неправильно ставите задачу. Вы все время думаете о реализации, а начинать надо с постановки цели. Когда есть цель, можно искать средства реализации. Если цели нет, то можно наплодить кучу реализаций, но их практическая ценность будет близка к нулю. |
Автор: EvilsInterrupt 20.1.2010, 18:21 |
2 baldina : >>Вы неправильно ставите задачу. Ну неужели я должен тут постить ситуацию заказчика ? Все его секреты и заскоки ? ИМХО, не имею права! Потому и придумываю ситуацию похоже на его! Ситуация проста, он хочет получить интерфейс и файл библиотеки, а я нехочу чтобы он хоть чтото знал о том как реализована. Малейшая мысль о том как сделано, сведет на нет работу, а lib-файл покрою протом, это же обыкновенный x86-код и формат не шибко отличается от тех PE-заморочек в привычных нам exe, dll, sys файлах!!! Пока пришел к выводу: 1) Создаю в инклуд базовый класс и + инструкцию которая в аргументе возвращает созданный объект потомка, ну и bool, как возвращаемое значение ф-ции. 2) В файлах реализации создаю потомки этого базового класса, ну и там же наследуюсь в еще один класс промежуточный class c_wrapper_animal : public c_basic_animal 3) В промежуточном c_wrapper_animal создаю все протектед методы, которые переопределяю и реализовываю в потомках 4) Реальные объекты создаются в зависимости от аргумента "at" функции bool create_animal(c_basic_animal * animal, animal_type at) , именно существование этой ф-ции упомяналось в п.1. Дальше компилю, протечу(защищаю протектором) и высылаю animal.h + animal.lib , на этом пока мои мысли завершены. Собственно пока на этом все! |
Автор: maxim1000 20.1.2010, 18:37 |
если у нас есть три набора информации, у каждой из которых разные пользователи, логично поместить её в три файла: в основном h-файле - информация для всех пользователей: описание класса, указатель на структуру с private-данными, указатель на структуру с protected-данными в дополнительном h-файле - информация для тех, кто захочет наследоваться: описание структуры с protected-данными основного класса в третьем файле (cpp или ещё один h) - информация для внутренней реализации класса: описание структуры с private-данными основного класса тогда каждый подключает тот файл, который ему нужен |
Автор: EvilsInterrupt 20.1.2010, 19:29 |
2 maxim1000 : Именно так и сделал! ;) Только допер до этого совсем не тогда когда тему создавал, а мысль на эту хрень натолкнулпост от mes сделанный в "20.1.2010, 01:23" |
Автор: olen 20.1.2010, 19:29 |
sgfsdfsdf |