I asked this question on Stack Overflow and in the comments someone had this to say.
In a proper design, you should almost never have to do a dynamic_cast, even if it's hidden inside some nice getter function.
Now this got me thinking a lot. I have been thinking of various ways in which I could eliminate the dynamic_cast
in question, or any cast for that matter from my code. Now I come here rather frustrated as the only thing I can think of to get rid of that cast; in that location is by doing the cast elsewhere.
So I ask, how can I improve upon this design?
#include <iostream>
#include <string>
// Properties for all components
class ComponentProperties {
public:
ComponentProperties( std::string componentProperty ):
componentProperty_( componentProperty ) { }
virtual ~ComponentProperties( ) { }
std::string getComponentProperty( ) const { return componentProperty_; }
protected:
std::string componentProperty_;
};
// Properties specific to Textboxes
class TextboxProperties: public ComponentProperties {
public:
TextboxProperties( std::string componentProperty, std::string textboxProperty ):
ComponentProperties( componentProperty ),
textboxProperty_( textboxProperty ) { }
std::string getTextboxProperty( ) { return textboxProperty_; }
private:
std::string textboxProperty_;
};
class Component {
public:
Component( ComponentProperties& properties ):
properties_( properties ) { }
virtual ~Component( ) { }
protected:
ComponentProperties& properties_;
};
class Textbox : public Component {
public:
Textbox( TextboxProperties& properties ):
Component( properties ) { }
// overload << purely for displaying properties.
friend std::ostream & operator << ( std::ostream& out, const Textbox& textbox );
};
std::ostream & operator << ( std::ostream& out, const Textbox& textbox ) {
return out << textbox.properties_.getComponentProperty( ) << ", "
<< dynamic_cast< TextboxProperties& >( textbox.properties_ ).getTextboxProperty( );
}
int main( ) {
TextboxProperties properties( "PropertyOne", "PropertyTwo" );
Textbox textbox( properties );
std::cout << textbox << std::endl;
return 0;
}