Re[2]: вопрос по объектно-ориентированному пронраммирован
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 14.05.04 09:10
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>
  • Матрица указателей на функции пересечения примитивов по идентификаторам, хранящимся в объекте (ad hoc rtti).
    ...
      ПК>
    • Достоинства: максимальная производительность, возможность добавления поиска пересечений новых примитивов без модификации исходных классов.
      ПК>
    • Недостатки: слабая интеграция с языком, в частности, невозможность поиска пересечений объектов унаследованных классов, необходимость поддержания набора уникальных идентификаторов.

    Здесь
    Автор: sergey_shandar
    Дата: 25.03.04
    , если интересно, реализованна мульти диспетчиризации построенная на N-мерном массиве указателей, с автоматическим заполнением и с устранением недостатка создания уникальных идентификаторов. Есть правда другой недостаток — создание списка используемых типов.
  • getboost.codeplex.com
    citylizard.codeplex.com
    Re[6]: все зависит от конкретной задачи
    От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
    Дата: 14.05.04 10:34
    Оценка:
    Здравствуйте, Павел Кузнецов, Вы писали:

    ПК>Наиболее практичным и гибким подходом, на мой взгляд, является использование RTTI с последующим "сползанием" в ту или иную форму таблицы функций.


    Павел, не могли бы Вы пояснить свою мысль фрагментом кода?
    Re: вопрос по объектно-ориентированному пронраммирован
    От: _Winnie Россия C++.freerun
    Дата: 14.05.04 10:43
    Оценка:
    У меня в движке так сделанно... никаких двойных виртуальных фунций, ибо отсекать нужно максимально быстро...
    Сорри, не могу сделать копи-паст, так что реализация не реализованна
    Я заранее знал, что у меня есть только шары и бибоксы

    #include <iostream>
    
    struct BoundingVolume
    {
    protected:
      enum { bbox=0, bsphere=1 } type_id;
      friend bool Intersect(const BoundingVolume &v1, const BoundingVolume &v2);
    };
    
    
    class BBox: public BoundingVolume
    {
    public:
      BBox() { type_id=bbox; }
    };
    
    class BSphere: public BoundingVolume
    {
    public:
      BSphere() { type_id= bsphere; }
    };
    
    bool Intesect_bb(const BoundingVolume &b1, const BoundingVolume &b2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    
    bool Intesect_bs(const BoundingVolume &b1, const BoundingVolume &s2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    
    bool Intesect_sb(const BoundingVolume &s1, const BoundingVolume &b2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    
    bool Intesect_ss(const BoundingVolume &s1, const BoundingVolume &s2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    
    typedef bool (*IntersectFunction_t)(const BoundingVolume &v1, const BoundingVolume &v2);
    
    const IntersectFunction_t IntersectFuctionsTable[4]=
    {
      Intesect_bb, Intesect_bs, Intesect_sb, Intesect_ss
    };
    
    bool Intersect(const BoundingVolume &v1, const BoundingVolume &v2)
    {
      return IntersectFuctionsTable[(v1.type_id<<1) + v2.type_id](v1, v2);
    }
    
    
    #include <iostream>
    
    int main()
    {
      BoundingVolume *pb = new BBox;
      BoundingVolume *ps = new BSphere;
    
      Intersect(*pb, *pb);
      Intersect(*pb, *ps);
      Intersect(*ps, *pb);
      Intersect(*ps, *ps);
    
    }
    Правильно работающая программа — просто частный случай Undefined Behavior
    Re[2]: вопрос по объектно-ориентированному пронраммирован
    От: Шахтер Интернет  
    Дата: 15.05.04 00:17
    Оценка:
    Здравствуйте, Павел Кузнецов, Вы писали:

    ПК>Здравствуйте Albatross, Вы писали:

    ПК>(Вопрос об организации поиска пересечений геометрических примитивов.)

    ПК>Мультиметоды — одна из фундаментальных проблем C++.


    Я думаю, это не проблема языка, как такового.

    ПК>На сегодняшний день можно выделить три способа решения задач связанных с множественной диспетчеризацией, и, в частности, поиска пересечений.


    Не могу удержаться. Я тут недавно постил свой сэмпл
    Автор: Шахтер
    Дата: 08.05.04
    .
    ... << RSDN@Home 1.1.0 stable >>
    В XXI век с CCore.
    Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
    Re[2]: вопрос по объектно-ориентированному пронраммирован
    От: sergey_shandar США http://getboost.codeplex.com/
    Дата: 16.05.04 04:59
    Оценка:
    Здравствуйте, _Winnie, Вы писали:

    _W>У меня в движке так сделанно... никаких двойных виртуальных фунций, ибо отсекать нужно максимально быстро...


    Вот тот же пример, только с применением kafe.

    struct BoundingVolume {};
    
    class BBox: public BoundingVolume {};
    
    class BSphere: public BoundingVolume {};
    
    //------------------------------------------------------------------------------
    
    #include <kafe/dispatch.hpp>
    
    namespace kafe
    {
    /// Определение наследников.
    template<>
    struct children<BoundingVolume>: boost::mpl::vector<BBox, BSphere> {};
    
    /// Определения возвращаемого типа.
    struct mix<boost::mpl::vector<BoundingVolume, BoundingVolume> >: 
        mix_helper<boost::mpl::vector<BoundingVolume, BoundingVolume>, bool>
    {
    };
    
    bool mix_func(const BBox *b1, const BBox *b2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    
    bool mix_func(const BBox *b1, const BSphere *b2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    
    bool mix_func(const BSphere *b1, const BBox *b2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    
    bool mix_func(const BSphere *b1, const BSphere *b2)
    {
      std::cout <<__FUNCSIG__ <<std::endl;
      return true;
    }
    }
    
    #include <iostream>
    
    int main()
    {    
        kafe::child<BoundingVolume, BBox> b;
        kafe::child<BoundingVolume, BSphere> s;
        
        kafe::call_mix_func(b, b);
        kafe::call_mix_func(b, s);
        kafe::call_mix_func(s, b);
        kafe::call_mix_func(s, s);
        
        std::cin.get();
    }


    А если функции не нужно возращать результат, и хочеться использовать шаблонные функции, то все будет выглядеть еще проще:
    struct BoundingVolume {};
    
    class BBox: public BoundingVolume {};
    
    class BSphere: public BoundingVolume {};
    
    //------------------------------------------------------------------------------
    
    #include <kafe/dispatch.hpp>
    
    namespace kafe
    {
    template<>
    struct children<BoundingVolume>: boost::mpl::vector<BBox, BSphere> {};
    
    template<class T1, class T2>
    void mix_func(const T1 *b1, const T2 *b2)
    {
      std::cout << typeid(T1).name() << " x " << typeid(T2).name() <<std::endl;
    }
    
    }
    
    #include <iostream>
    
    int main()
    {    
        kafe::child<BoundingVolume, BBox> b;
        kafe::child<BoundingVolume, BSphere> s;
        
        kafe::call_mix_func(b, b);
        kafe::call_mix_func(b, s);
        kafe::call_mix_func(s, b);
        kafe::call_mix_func(s, s);
        
        std::cin.get();
    }


    getboost.codeplex.com
    citylizard.codeplex.com
    Re[3]: вопрос по объектно-ориентированному пронраммирован
    От: Кодт Россия  
    Дата: 16.05.04 10:45
    Оценка: +1
    Здравствуйте, Шахтер, Вы писали:

    ПК>>Мультиметоды — одна из фундаментальных проблем C++.


    Ш>Я думаю, это не проблема языка, как такового.


    Это проблема ООП вообще.

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

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

    Есть разные реализации мультиметодов.
    Самые популярные — это
    1. Обработчик-сообщение (преимущество первого аргумента)
    2. Двойная диспетчеризация (преимущество второго аргумента)
    3. Первый подошедший (в порядке регистрации сигнатур)
    4. Точное совпадение (всё, что не подошло — вызывает дефолт)
    отличающиеся в первую очредь порядком (а уже потом — техникой воплощения).
    Ну и ещё пару схем могу привести, но они затейливые.

    Короче говоря, перед тем, как кодировать мультиметоды — нужно объяснить себе, что же в самом деле должно происходить между каждой парой классов. А не только между теми, для которых существуют сигнатуры мультиметода.
    ... << RSDN@Home 1.1.2 stable >>
    Перекуём баги на фичи!
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.