C++ C++;模板和虚拟继承
假设我有一个类的层次结构:C++ C++;模板和虚拟继承,c++,templates,inheritance,visitor-pattern,C++,Templates,Inheritance,Visitor Pattern,假设我有一个类的层次结构: class Animal; class Cat: public Animal; class Dog: public Animal; 这些类不是模板化的。我还有另一个平行的模板类层次结构: template<class T> class Drawer; template<class T> class CatDrawer: public Drawer<T>; template<class T> class DogDrawe
class Animal;
class Cat: public Animal;
class Dog: public Animal;
这些类不是模板化的。我还有另一个平行的模板类层次结构:
template<class T> class Drawer;
template<class T> class CatDrawer: public Drawer<T>;
template<class T> class DogDrawer: public Drawer<T>;
我不想这样做,因为这样做的唯一目的是支持创建抽屉实例,而这将污染大部分代码,否则就不需要模板
2) 奇怪的递归模板模式。我觉得这样可以工作,但是这会阻止我在Animal
上创建指针容器
3) 使用访客;这将允许将调用create_drawer()
分为两部分,一部分在Animal
上,它将记录我们想要创建一个抽屉的事实,另一部分在visitor上,它将以非虚拟的方式创建模板化的抽屉
class Animal{
virtual void accept(DrawerCreatorVisitor v) = 0;
};
class Dog: public Animal{
virtual void accept(DrawerCreatorVisitor v){
v.visit(*this);
};
}
...
class DrawerCreatorVisitor{
public:
template<class T>
shared_ptr<Drawer<T>> make_drawer(Animal& animal){
animal.accept(*this); // double dispatch which will set the to_create member
if(to_create == _dog)
return shared_ptr<Drawer<T>>(new DogDrawer<T>(static_cast<Dog&>(animal)));
if(to_create == _cat)
return shared_ptr<Drawer<T>>(new CatDrawer<T>(static_cast<Cat&>(animal)));
};
void visit(Dog dog){
to_create = _dog;
};
void visit(Cat cat){
to_create = _cat;
};
private:
enum Drawable {_dog, _cat};
Drawable to_create;
};
类动物{
虚拟作废接受(付款人或访客v)=0;
};
犬类:公共动物{
虚拟作废接受(付款人创建人v){
v、 访问(*本);
};
}
...
类DroperCreatorVisitor{
公众:
模板
共用抽屉(动物和动物){
accept(*this);//双重分派,将设置为创建成员
如果(创建==\u狗)
返回共享\u ptr(新的狗抽屉(静态\u石膏(动物));
如果(创建==\u cat)
返回共享\u ptr(新CatDrawer(静态\u石膏(动物));
};
无效访问(狗){
创建=\u狗;
};
无效访问(Cat){
创建=\u cat;
};
私人:
枚举可绘制{u狗,{u猫};
可绘制,可创建;
};
这似乎有效;调用语法正常:
DrawerCreatorVisitor dcv;
shared_ptr<Drawer<int>> dcv.make_drawer<int>(the_dog);
drawercreatorvisitordcv;
共用抽屉(狗);
你能看出有什么缺点/改进的方法吗?此外,我还没有真正发现这个主题的负载,这是否意味着我最初的设计是错误的?非常感谢:)为什么不在
Animal
上使用virtual Draw()=0
方法呢?因为给定一组动物,我需要在开始绘制任何东西之前创建所有的抽屉
class Animal{
virtual void accept(DrawerCreatorVisitor v) = 0;
};
class Dog: public Animal{
virtual void accept(DrawerCreatorVisitor v){
v.visit(*this);
};
}
...
class DrawerCreatorVisitor{
public:
template<class T>
shared_ptr<Drawer<T>> make_drawer(Animal& animal){
animal.accept(*this); // double dispatch which will set the to_create member
if(to_create == _dog)
return shared_ptr<Drawer<T>>(new DogDrawer<T>(static_cast<Dog&>(animal)));
if(to_create == _cat)
return shared_ptr<Drawer<T>>(new CatDrawer<T>(static_cast<Cat&>(animal)));
};
void visit(Dog dog){
to_create = _dog;
};
void visit(Cat cat){
to_create = _cat;
};
private:
enum Drawable {_dog, _cat};
Drawable to_create;
};
DrawerCreatorVisitor dcv;
shared_ptr<Drawer<int>> dcv.make_drawer<int>(the_dog);