Right design pattern to deal with polymorphic collections of objects

后端 未结 5 1081
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-22 04:59

Suppose I have the following classes:

class BaseObject {
    public:
        virtual int getSomeCommonProperty();
};

class Object1: public BaseObject {
    publ         


        
5条回答
  •  孤独总比滥情好
    2021-01-22 05:43

    Id use nested adapter as in below example. You have to specialize it for every class you want to do a fancy update !The example has memory leak - allocated A, B, Q objects are not deleted!

    #include 
    #include 
    #include 
    class Q
    {
    public:
        virtual void Foo()
        {
            std::cout << "Q::Foo()" << std::endl;
        }
    };
    class A
    {
    
    public:
        virtual void Foo()
        {
            std::cout << "A::Foo()" << std::endl;
        }
    };
    
    class B : public A
    {
    public:
        virtual void Foo()
        {
        std::cout << "B::Foo()" << std::endl;
        }
        virtual void BFoo()
        {
            std::cout << "B::BFoo()" << std::endl;
        }
    };
    
    template 
    class C
    {
    public:
        template 
        void add(T* ptr){m_Collection.push_back(std::unique_ptr(new ConcreteAdapter(ptr)));}
        void updateAll()
        {
            std::for_each(m_Collection.begin(), m_Collection.end(), [&](std::unique_ptr &adapter)->void{adapter->update();});
        }
    private:
        class Adapter
        {
        public:
            virtual ElementType* get() = 0;
            virtual void update(){get()->Foo();}
    
        };
        template 
        class ConcreteAdapter : public Adapter
        {
        public:
            ConcreteAdapter(T* ptr) : m_Ptr(ptr){}
            virtual T* get(){return m_Ptr;}
        protected:
            T* m_Ptr;
        };
    
        template <>
        class ConcreteAdapter : public Adapter
        {
        public:
            ConcreteAdapter(B* ptr) : m_Ptr(ptr){}
            virtual B* get(){return m_Ptr;}
            virtual void update()
            {
            get()->Foo();
            get()->BFoo();
            }
        private:
            B* m_Ptr;
    
        };
        std::vector> m_Collection;
    };
    int main()
    {
        C c;
        c.add(new A());
        c.add(new B());
        //c.add(new Q()); //error - correct
        c.updateAll();
        return 0;
    }
    

提交回复
热议问题