Re: How can I remove dynamic_cast and if statements from this code snippet?
On Nov 16, 2:12 pm, Ian Collins <ian-n...@hotmail.com> wrote:
So how would a generic drawing class be expected to know this?
This is basically the question I am asking this group.
Below is a pseudocode answer to the question that
- leaves Shape, Circle, and Square untouched (good)
- places no drawing dependency on the shapes (good)
- leaves drawing code entirely in the Drawer classes (good)
- does not have switch or if statements (good)
* does use a dynamic cast (BAD)
Can you (or anyone else) come up with some c++ pseudocode that
- leaves Shape, Circle, and Square untouched (good)
- places no drawing dependency on the shapes (good)
- leaves drawing code entirely in the Drawer classes (good)
- does not have switch or if statements (good)
- does not use a dynamic cast (good)
Chris
=====
//----------
struct Drawer
{
virtual void Draw(Shape* shape) = 0;
};
//----------
struct CircleDrawer : public Drawer
{
void Draw(Shape* shape)
{
// dynamic_cast<Circle*>(shape)
// draw the circle
}
};
//----------
struct SquareDrawer : public Drawer
{
void Draw(Shape* shape)
{
// dynamic_cast<Square*>(shape)
// draw the square
}
};
//----------
struct DrawerCreator
{
virtual Drawer* GetNewDrawer() = 0;
virtual bool CanDraw(Shape* shape) = 0;
};
//----------
struct CircleDrawerCreator : public DrawerCreator
{
Drawer* GetNewDrawer() { return new CircleDrawer; }
bool CanDraw(Shape* shape) { return dynamic_cast<Circle*>(shape); }
};
//----------
struct SqareDrawerCreator : public DrawerCreator
{
Drawer* GetNewDrawer() { return new SquareDrawer; }
bool CanDraw(Shape* shape) { return dynamic_cast<Square*>(shape); }
};
//----------
struct DrawerManager
{
void RegisterDrawerCreator(DrawerCreator* dc)
{
drawers.push_back(dc);
}
void Draw(Shape* shape)
{
if (Drawer* drawer = GetDrawer(shape))
{
drawer->Draw(shape);
}
}
Drawer* GetDrawer(Shape* shape)
{
for (int i = 0; i < drawers.size(); ++i)
{
if (drawers[i]->CanDraw(shape))
{
return drawers[i]->GetNewDrawer();
}
}
return 0;
}
vector<Drawer*> drawers;
};
//----------
int main()
{
DrawerManager drawer_manager;
drawer_manager.RegisterDrawerCreator(new CircleDrawerCreator);
drawer_manager.RegisterDrawerCreator(new SquareDrawerCreator);
Shape* shape1 = new Circle;
Shape* shape2 = new Square;
drawer_manager.Draw(shape1);
drawer_manager.Draw(shape2);
}