![]() |
How can I remove dynamic_cast and if statements from this code snippet?
Hello,
I would like to remove the "dynamic_cast" and "if" statements from the code below. I believe some people would describe this as making the code "polymorphic". Can you recommend a way to do this without modifying the original classes in "Library A"? My intention is to create an "XML Writer" class(es) for shapes without putting "XML code" in the base classes. I plan to use a similar pattern for drawing and other tasks my application has to perform on Shape objects. Thank you, Chris // Library A struct Shape { virtual ~Shape() {} }; struct Circle : public Shape { float radius; }; struct Square : public Shape { float edge; }; // Library B #include <iostream> class XmlWriter { static void write(Shape* shape) { if (Circle* circle = dynamic_cast<Circle*>(shape)) { std::cout << "<Circle Radius=" << circle->radius << "/>"; } else if (Square* square = dynamic_cast<Square*>(shape)) { std::cout << "<Square Edge=" << square->edge << "/>"; } } }; |
Re: How can I remove dynamic_cast and if statements from this codesnippet?
On 11/17/11 07:37 AM, Chris Stankevitz wrote:
> Hello, > > I would like to remove the "dynamic_cast" and "if" statements from the > code below. I believe some people would describe this as making the > code "polymorphic". Can you recommend a way to do this without > modifying the original classes in "Library A"? > > My intention is to create an "XML Writer" class(es) for shapes without > putting "XML code" in the base classes. I plan to use a similar > pattern for drawing and other tasks my application has to perform on > Shape objects. > > Thank you, > > Chris > > // Library A > struct Shape { virtual ~Shape() {} }; > struct Circle : public Shape { float radius; }; > struct Square : public Shape { float edge; }; > > // Library B > #include<iostream> > > class XmlWriter > { > static void write(Shape* shape) > { > if (Circle* circle = dynamic_cast<Circle*>(shape)) > { > std::cout<< "<Circle Radius="<< circle->radius<< "/>"; > } > else if (Square* square = dynamic_cast<Square*>(shape)) > { > std::cout<< "<Square Edge="<< square->edge<< "/>"; > } > } > }; Something like: struct Shape { virtual void write() = 0; }; struct Circle : public Shape { float radius; void write() { std::cout<< "<Circle Radius="<< circle->radius<< "/>"; } }; struct Square : public Shape { float edge; void write() { std::cout<< "<Square Edge="<< square->edge<< "/>"; } }; class XmlWriter { static void write(Shape* shape) { shape->write(); } }; -- Ian Collins |
Re: How can I remove dynamic_cast and if statements from this code snippet?
On Nov 16, 10:52*am, Ian Collins <ian-n...@hotmail.com> wrote:
> Something like: > > struct Shape { > * *virtual void write() = 0;}; Ian, I prefer/require a solution in which the shapes themselves are not writing out XML -- I want the XML related code restricted to the "XmlWriter" class in "Library B". This appears to be an overly draconian requirement in this simple example, but should make more sense if you consider adding something like a "drawing" or "network" class that would introduce dependencies on drawing or socket code. I want drawing/xml/socket code relegated to "Library B" without compile or link dependencies in "Library A". Thank you, Chris |
Re: How can I remove dynamic_cast and if statements from this codesnippet?
On 11/16/2011 11:14 AM, Chris Stankevitz wrote:
> On Nov 16, 10:52 am, Ian Collins<ian-n...@hotmail.com> wrote: >> Something like: >> >> struct Shape { >> virtual void write() = 0;}; > > Ian, > > I prefer/require a solution in which the shapes themselves are not > writing out XML -- I want the XML related code restricted to the > "XmlWriter" class in "Library B". This appears to be an overly > draconian requirement in this simple example, but should make more > sense if you consider adding something like a "drawing" or "network" > class that would introduce dependencies on drawing or socket code. > > I want drawing/xml/socket code relegated to "Library B" without > compile or link dependencies in "Library A". > You are somewhat correct here. Have the "write" function return a string which the XML code can display. By divorcing the I/O from the representation return, you're more general anyways. BTW, what book are you reading? This fragment/problem is actually one of the canonical OOP examples. class Shape { public: //... virtual std::string as_string() = 0; } class Square { //... std::string as_string() { return "Edge..." }; } class |
Re: How can I remove dynamic_cast and if statements from this code snippet?
On Nov 16, 12:03*pm, red floyd <no.spam.h...@its.invalid> wrote:
> You are somewhat correct here. *Have the "write" function return > a string which the XML code can display. *By divorcing the I/O from > the representation return, you're more general anyways. Red, Thank you for your reply. I believe you have attempted to solve my problem by modifying the original shapes to return their "XML components" as strings. Unfortunately this is not what I am interested in because it does not scale to what I really want to do. Instead of writing a long-winded response that might not come across correctly, allow me to change my original question to use drawing instead of string writing: === Is it possible in C++ to modify "Library B" below to eliminate the dynamic_cast and switch statements, while at the same time not doing any of the following: - Do not use DeviceContext in "Library A" - Do not put drawing code in "Library A" - Do not put the concept of drawing into "Library A" including adding a class Shape::GetPixelsToDraw My goal is to a) not put any reference to drawing into Library A b) not use dynamic_cast or switch/if blocks in Library B The answer might be something like "use factories" or "use template" or "this is not possible in c++". Thank you, Chris // Library A struct Shape { virtual ~Shape() {} }; struct Circle : public Shape { float radius; }; struct Square : public Shape { float edge; }; // Library B #include <cmath> struct DeviceContext { void FillPixel(int PixelX, int PixelY) {}; }; class Drawer { static void write(Shape* shape, DeviceContext& Dc) { if (Circle* circle = dynamic_cast<Circle*>(shape)) { for (float Angle = 0; Angle < 2*3.14156; Angle += 0.1) { Dc.FillPixel(cos(Angle) * circle->radius, sin(Angle) * circle- >radius); } } else if (Square* square = dynamic_cast<Square*>(shape)) { Dc.FillPixel(0, 0); Dc.FillPixel(square->edge, 0); Dc.FillPixel(square->edge, square->edge); Dc.FillPixel(0, square->edge); } } }; |
Re: How can I remove dynamic_cast and if statements from this codesnippet?
On 11/17/11 08:14 AM, Chris Stankevitz wrote:
> On Nov 16, 10:52 am, Ian Collins<ian-n...@hotmail.com> wrote: >> Something like: >> >> struct Shape { >> virtual void write() = 0;}; > > Ian, > > I prefer/require a solution in which the shapes themselves are not > writing out XML -- I want the XML related code restricted to the > "XmlWriter" class in "Library B". This appears to be an overly > draconian requirement in this simple example, but should make more > sense if you consider adding something like a "drawing" or "network" > class that would introduce dependencies on drawing or socket code. > > I want drawing/xml/socket code relegated to "Library B" without > compile or link dependencies in "Library A". Well you have to look seriously at whether a shape knows how to write its self, or an XmlWriter knows how to write a shape. If it's the latter, you gave to provide a means for an XmlWriter to access the required information. This can lead to significant complexity and coupling in your design. It gets more complex still if you consider drawing a shape. -- Ian Collins |
Re: How can I remove dynamic_cast and if statements from this code snippet?
On Nov 16, 12:35*pm, Leigh Johnston <le...@i42.co.uk> wrote:
> * * * * virtual void write(const serializer& writer) const Leigh, Thank you for your reply. I believe you have effectively modified the base class to return the XML components as strings. This is not what I am attempting to do as it requires me to modify the base class to assume it will be serialized. I'm looking for an approach in which the base class is not modified or at least is modified only in a way that allows a Factory or Template or some other technique to give shape details to another library. I do not want to modify the base class to share "serializing" details. I try to explain this a little better in my reply to Red. Thank you, Chris |
Re: How can I remove dynamic_cast and if statements from this code snippet?
On Nov 16, 1:37*pm, Ian Collins <ian-n...@hotmail.com> wrote:
> Well you have to look seriously at whether a shape knows how to write > its self, or an XmlWriter knows how to write a shape. *If it's the > latter, you have to provide a means for an XmlWriter to access the > required information. Yes, it is the latter that I would like to do. >*This can lead to significant complexity Yes, I am looking for complexity and am curious if it is possible to do this with c++. > It gets more complex still if you consider drawing a shape. Yes, I am trying to draw Shapes without Shapes knowing how to draw themselves. Is it possible to do this in c++ without using dynamic_cast or lots of switch/if statements? Thank you, Chris |
Re: How can I remove dynamic_cast and if statements from this code snippet?
On Nov 16, 1:39*pm, Leigh Johnston <le...@i42.co.uk> wrote:
> struct DrawableCircle : Circle, Drawable Unfortunately the object that creates my shapes cannot create DrawableShapes as that library has no dependency on or knowledge of the concept of drawing. But thank you for continuing to attempt to help me. Chris |
Re: How can I remove dynamic_cast and if statements from this codesnippet?
On 11/17/11 10:41 AM, Chris Stankevitz wrote:
> On Nov 16, 1:37 pm, Ian Collins<ian-n...@hotmail.com> wrote: >> Well you have to look seriously at whether a shape knows how to write >> its self, or an XmlWriter knows how to write a shape. If it's the >> latter, you have to provide a means for an XmlWriter to access the >> required information. > > Yes, it is the latter that I would like to do. > >> This can lead to significant complexity > > Yes, I am looking for complexity and am curious if it is possible to > do this with c++. > >> It gets more complex still if you consider drawing a shape. > > Yes, I am trying to draw Shapes without Shapes knowing how to draw > themselves. Is it possible to do this in c++ without using > dynamic_cast or lots of switch/if statements? The problem has little to do with C++. The issue of who knows how to do what is common to any language. The literal answer to your question is yes. You can always replace conditionals with virtual member functions. -- Ian Collins |
| All times are GMT. The time now is 04:19 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.