如何使用非模板类传递模板对象?

来源:互联网 发布:有关程序员的个性签名 编辑:程序博客网 时间:2024/06/03 20:14
设想一个使用场景:有各种类型对象A,B,C...,这些对象在系统中创建和使用是相分离的,如何搬运这些不同类型的数据对象?好比是购物,不同用户买了不同商品,快递员使用包裹包装这些商品,由卖家将商品打包后,交给快递公司,最后客户收到包裹,拆开包裹后取到商品。
如果这些数据对象没有一个共同的基类,如何将这些对象打包?

考虑有一个包裹类Wrapper,里面可以存放各种类型的对象,可能写的如下

template<typename T>class Wrapper{public:    Wrapper(T* p) : _p(p) {}    T* get() const { return _p; }private:    T* _p;};
使用场景如下:
class CreatorA{public:    const Wrapper<A>& getA() { return _d; }private:    Wrapper<A> _d;};class UseA{public:    void useA(const Wrapper<A>& d) { A* a = d.get(); }};
需要传递具体类型,不具有通用性。
可以考虑将类型对象移出包裹类,放在一个其他模板对象中,比如:
template<typename T>class WrapperImp{public:    WrapperImp(T* p): _p(p){}    T* get() const { return _p; }private:    T* _p;};
修改Wrapper后:
class Wrapper{public:    Wrapper(){}    template<typename T>    void set(T* p) {}private:    WrapperImp<T> m_imp;};
写到这里发现,包裹类仍然需要模板类型。再进一步,考虑把imp类提取基类,这样包裹类中只需要保留基类对象指针就可以了。
完整代码如下:

#include <iostream>class WrapperImpBase{public:    WrapperImpBase(){}    virtual ~WrapperImpBase(){}};template<typename T>class WrapperImp : public WrapperImpBase{public:    WrapperImp(T* ptr = 0)        :m_ptr(ptr){}    T* get() const { return m_ptr; }private:    T* m_ptr;};class Wrapper{public:    template<typename T>    Wrapper(T* ptr)    {        m_imp = new WrapperImp<T>(ptr);    }    ~Wrapper()    {        delete m_imp;    }    template<typename T>    T* get() const    {        if (m_imp)        {            WrapperImp<T> * imp = dynamic_cast<WrapperImp<T>*>(m_imp);            return imp->get();        }        return 0;    }private:    WrapperImpBase* m_imp;};

原创粉丝点击