Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание класса-обертки 
:(
    Опции темы
REZiaMIX
Дата 27.10.2008, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Есть класс TAnimation , с функцией Render... Функция использует глобальные переменные(от которых в посл. надо избавиться) .
+ класс TAnimations (метод Render тоже присутствует), представляющий собой массив анимаций , и функции для массовой их обработки - в чистом виде не используется , только наследуется.
Итого , имеем множество классов например:
TBullets,THumans - все наследуют TAnimations.
Надо сделать класс-обертку для всей анимации, но проблема в том , что классов может быть неизвестное кол-во , и каждый раз дописывать код в обертку не красиво и не гибко.
Каким образом реализовать такой класс(в полиморфизме и тд не очень разбираюсь) , с учетом того , что у всех исходных есть функция Render?

Пояснение:
Код

class TAnimation
{
    void Render(...){...};
};

class TAnimations
{
    vector <TAnimation> AllAnims; 
    
    void RenderAll(...)
    {
        // Рендрим все объекты из списка
    }
};


class THumans : public TAnimations
{
....
};

class TBullets : public TAnimations
{
....
};

class All {
 // сюда переписываем глобальные переменные
 ???? THumans ????
 ???? TBullets ????
    void RenderAll
    {
        /// ... рендрим все
    }
};



Есть вариант , хранить в векторе указатель на функции рендера , и вызывать их в цикле,
но все исходные классы должны получать те глобальные переменные(можно передать как аргумент).
Но что то мне подсказывает , что есть более правильный выход!

В идеале бы хотелось так(понятно что не будет работать , но для примера):
Код

TBullets bullets1;
THumans humans1;

TAll AllObjects;
AllObjects.push_back(bullets1);        //error   
AllObjects.push_back(humans1);     //error
AllObjects.RenderAll(...);


Заранее сенкс за ответы!



Это сообщение отредактировал(а) REZiaMIX - 27.10.2008, 23:04


--------------------
user posted image
PM MAIL   Вверх
mes
Дата 27.10.2008, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Код

class IAnimation
{
   public:
         virtual void Render (..) = 0;
};

class Animations
{
    public:
       void Clear() {..};
       void AddAnimation    ( IAnimation * p) { ... }
       void RemoveAnimation ( IAnimation * p) { ... }
       void Render (.. ) {  for  (std::vector<IAnimation* >::iterator it = m_vAnim.begin(); it!=m_vAnim.end(); ++it)  if (*it) *it->Render(...);  }

    private:
       std::vector<IAnimation* > m_vAnim;
};

class Human : public IAnimation
{
   public:
         virtual void Render (..) { ... }
};

class Bullet : public IAnimation
{
   public:
         virtual void Render (..) { ... }
};
... 
Animations anims; 
anims.AddAnimation (new Human);
anims.AddAnimation (new Human);
anims.AddAnimation (new Bullet);
anims.Render (..);


Это сообщение отредактировал(а) mes - 27.10.2008, 23:17


--------------------
PM MAIL WWW   Вверх
REZiaMIX
Дата 27.10.2008, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Этот кусок кода уже реализован , вопрос стоит в другом;
Код

class TAllAnimation
{
       TBullets AllBullets;
       THumans AllHumans;
       //Каждый раз добавлять
      
        void RenderAll(...)
        {
                  AllBullets->Render(...);
                  AllHumans->Render(...);
                  //Каждый раз добавлять
        }
};


Соответственно если я напишу класс TFlowers, то в класс TAllAnimation надо будет дописать TFlowers в двух местах , 
нужно сделать обобщенный рендер , не в зависимости от класса(при условии наличия у них фции render)

Цитата

std::vector<IAnimation* > m_vAnim;

Не будет ли ошибкой добавление в вектор указателя на TBullets , приведенного к указ. на IAnimation( (IAnimation*)&TBullets )???
//ПС , точнее его дальнейшее использование !


Это сообщение отредактировал(а) REZiaMIX - 27.10.2008, 23:22


--------------------
user posted image
PM MAIL   Вверх
mes
Дата 27.10.2008, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



вот подправил пример под вашу задачу:
Код

class TAllAnimation
{
    public:
       void Clear() {..};
       void AddAnimations       (TAnimations * p) { ... }
       void RemoveAnimations ( TAnimations * p) { ... }
       void RenderAll  (..) {  for  (std::vector<TAnimations* >::iterator it = m_vAnims.begin(); it!=m_vAnims.end(); ++it)  if (*it) *it->Render(...);  }
    private:
       std::vector<TAnimations* > m_vAnims;
};

TAllAnimation all_anims;
all_anims.Add (new ТBullets);
all_anims.Add (new ТHumans);
all_anims.RenderAll (..);

однако советую разобраться с полиморфизмом, чтоб найти к Вашей задаче наиболее подходящее решение  smile 

Это сообщение отредактировал(а) mes - 27.10.2008, 23:26


--------------------
PM MAIL WWW   Вверх
Torsten
Дата 28.10.2008, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: 3
Всего: 7



Цитата(REZiaMIX @  27.10.2008,  23:19 Найти цитируемый пост)
нужно сделать обобщенный рендер , не в зависимости от класса(при условии наличия у них фции render)

Предлагаю тебе сделать условие, не при наличии фции, а при наследовании определенного класса.
А сделать это очень просто.

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

Фишка в том что в конструкторе этого базового класса (у которого есть виртуальный метод Render) тебе нужно вызвать метод сигнлотона и добавить в этот список этот обьект.
В коде это примерно так должно выглядеть :

Код

class RenderObject
{
public:
      RenderObject() { RenderContainer::Instance().Add(this); }
      void Render() { RenderImpl(); }       

private:
      virtual void RenderImpl() = 0;
};

class RenderContainer : public Singletone<RenderContainer>
{
public:
     void Add(RenderObject * p)
     {
            m_List.push_back(p);
     }
 
     virtual ~RenderContatainer() {  /*очищаем элементы конейнера вручну, или можно std дек заменить на boost::deque_ptr, для автоматичского удаления*/ }

private:
     typedef std::deque<RenderObject*> RenderObjectsList;
    RenderObjectsList  m_List;
};


Ну и класса RenderContainer соотвественно метод, который вызовет через цикл у всех обьектов Render метод Rendor. Все что нужно будет сделать - унаследовать твой обьект от класс RenderObject, определить в нем RenderImpl() и создать этот обьект, он сам добавится в конейнер, причем сделать это можно в любой части программы.

Естественно в синглтон можно и твои глоб. переменные запихнуть, как раз ты сможешь тогда эти переменные передавать методу Render если это будет нужно.

Это сообщение отредактировал(а) Torsten - 28.10.2008, 15:15
--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
mes
Дата 28.10.2008, 19:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Цитата(Torsten @  28.10.2008,  15:08 Найти цитируемый пост)
Создаешь класс контейнер - сигнлтон, в котором хранится список всех обьектов которые нужно отредерить - т.е. указатели на базовые класс.

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



--------------------
PM MAIL WWW   Вверх
REZiaMIX
Дата 29.10.2008, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Всем спасибо , буду разбираться!


--------------------
user posted image
PM MAIL   Вверх
Torsten
Дата 29.10.2008, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: 3
Всего: 7



Цитата(mes @  28.10.2008,  19:09 Найти цитируемый пост)
а зачем в данном случае синглетон?  а вобще это плохая тенденция применять патерны где они не нужны, только потому что у них название звучное..

потому что удобно. Зачем - чтобы иметь возможность доступа к обьекту из любой точки. И насколько я понял обьект этот 1 и смысл создовать таких обьектов более 1 - нету.
--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

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


 




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


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

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