设想一个使用场景:有各种类型对象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;
};