![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Rickert |
|
|||
![]() Ситхи не пройдут! ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3356 Регистрация: 11.7.2006 Где: Лакрима Репутация: 0 Всего: 52 |
Так и не смог реализовать такую вещь: у меня есть класс, в котором должен быть список объектов, с разным кол-вом параметров.
Теперь смысл в следующем: как мне добавлять в список объекты типа demoClass, demoClass2, чтобы потом, внутир classContainer, распозновать их по типу и работать с ними? Придумал только вместо списка делать указатель типа void. -------------------- Ни что не внушает сна крепче, чем день приисполненный трудов! |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
в принципе, если ты точно знаешь тип объекта, можно просто привести тип и все |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
посмотрите патерн visitor, может подойти для вашей задачи
|
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
боже мой
да забудьте вы уже эти касты во-первых, как правильно заметил mes, есть паттерн visitor для сложных вещей. для простых вполне достаточно полиморфизма:
|
|||
|
||||
Lycifer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 4.11.2007 Репутация: нет Всего: нет |
Базовый класс имеет такое:
enum typeClass{typeBaseClass,typeClassChildren1,typeClassChildren2} class baseClass { protected: baseClass(){}//можно все перегрузить дабы не кто не создал объект этого класса кроме наследников public: virtual typeClass getType(){return typeBaseClass;} }; Реализация наследников class ClassChildren1 : baseClass { typeClass getType(){typeClassChildren1;} }; class ClassChildren2 : baseClass { typeClass getType(){typeClassChildren2;} }; Используется: void SomeFunctionClassChildren1(ClassChildren1 obj) { } void SomeFunctionClassChildren2(ClassChildren2 obj) { } void SomeFunction(baseClass obj) { switch(obj. getType()) { case typeClassChildren1: SomeFunctionClassChildren1((ClassChildren1)obj);//здесь можно и явное приведение break; case typeClassChildren1: SomeFunctionClassChildren2((ClassChildren2)obj);//здесь можно и явное приведение break; default: assert(false); } } } |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот пример, если классический полиморфизм не подходит и известны на стадии компиляции все используемые типы иерархии
Это сообщение отредактировал(а) mes - 8.11.2008, 16:05 |
|||
|
||||
Lycifer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 4.11.2007 Репутация: нет Всего: нет |
![]() ![]() И как же будеш узновать где какой тип ? А не тоже самое с раздувжемся кодом ? А производительность?(не стоит забывать что С++ язык статичиский, визитор это пример более динамического обращения, мой пример можно без проблем перевести к стратегиям что еще ускорит скорость, и к рамеру exe не будет увеличен) ![]() |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
а твой switch не раздувание кода? ![]() |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
это, извиняюсь за мой французский, через жопу называется ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
более точным будет выражение классическое примение полиморфизма, что в принципе означает стандартное применение виртуальных функций. Этим и хорош код, что узнавать какой тип будет компилятор, а программисту лишь надо описать реализацию действия, например ваш участок кода с самостоятельным слежением за типами и типопреобразованиями аналогичен этому, в котором черная работа осталась за кадром:
Ну и что удобней ? Двойной вызов виртуальной функции - вот и все накладные расходы. Вот вот - не стоит забывать, что Сpp является языком со статической типизацией. Именно на этой возможности и основан паттерн визитор и в своем исполнении не имеет ни капли динамического типопреобразования . Таблица переходов будет определена еще на этапе компиляции. Интересно с чего взяли про увелечение кода, при использовании визитора ? ) Визитор - это статический свитч, определеный как (в данном случае 2хмерная) таблица переходов, заполняемая и контролируемая, компилятором. Это сообщение отредактировал(а) mes - 8.11.2008, 16:06 |
|||
|
||||
UnrealMan |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Юзай boost::ptr_list |
|||
|
||||
Lycifer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 4.11.2007 Репутация: нет Всего: нет |
- покажи что ты умееш - Умееш так , тогда делай вот это ..... - А так ты так не умееш тогда делай по другому .... Но в моём примере есть не достаток когда код растет(Добовляются новые классы удалять старые очень сложно особенно если это по коду разброссано, но это уже другой разговор) |
|||
|
||||
mes |
|
||||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Ага все остается на совести программиста, и если он забыл посетить один из дальних уголков, то поведение системы непредсказуемо. Второй недостаток, что в каждой точке программы надо помнить что умеет делать каждый из объектов и как.
А чем хуже такое ? - а ну ка выполни это так, как умеешь. Но чтоб было хорошо! Основная прелесть ООП в том, что можно заставить объект самого решать поставленую задачу. Механизм виртуальных функций, помогает в этом, позволяя осуществить позднее связывание реализации с интерфейсом и при этом соблюсти все проверки типов на стадии компиляции. Классический полиморфизм используются для решния задач, когда кол-во выполняемых стабильно, в отличии от иерархии классов. Т.е мы знаем интерфейс но не знаем сколько и каких объектов будет. Двойная диспатчеризация (паттерн визитор) применяется в обратном случае, когда иерархия известна и стабильна, но интерфейс должен допускать легкое расширение функционала.
вот код показывающий имя типа, аналогично можно добавить числовый идентификатор, чтоб узнавать его и использовать в любой момент времени ![]() (основан на классах из предыдущего примера)
|
||||||
|
|||||||
Lycifer |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 4.11.2007 Репутация: нет Всего: нет |
А если выполнить надо операции не имеющиго прямого связаности с классом? А тогда все просто мы просто зделаем прямую зависимоть нашего VISITOR от старонних действий!! 1)Локализация логики - чего? не она негодится мы же программисты серьёзные мы все зделаем в одном VISITOR'S(набит как самосат но работает......) 2)VISITOR'S он способен выполнить действия которые были у него внутри, то и есть что бы он что-то еще выполнил лезим во все классы, а что? Нам что не хочется перелопатить еще строк так это N стока? Да не , мы же программисты и постоянная отладка и печать текста нам по приколу...... 3)
4) Динамический полиморфизм стал классическим ![]() 5)
|
||||||
|
|||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |