patterncppMinor
Avoiding casts in abstract types
Viewed 0 times
abstractavoidingcaststypes
Problem
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
So I ask, how can I improve upon this design?
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
#include
// 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 ( textbox.properties_ ).getTextboxProperty( );
}
int main( ) {
TextboxProperties properties( "PropertyOne", "PropertyTwo" );
Textbox textbox( properties );
std::cout << textbox << std::endl;
return 0;
}Solution
The best solution is to make
Advantage of doing it this way is you can get rid of this getter methods.
ComponentProperties know how to print itself.class ComponentProperties {
friend std::ostream& operator<<(std::ostream& s, ComponentProperties const& d) {
return d.print(s);
}
virtual std::ostream& print(std::ostream& s) const {
return s << componentProperty_;
}
// STUFF
};
class TextboxProperties: public ComponentProperties {
virtual std::ostream& print(std::ostream& s) const {
return ComponentProperties::print(s) << ", " << textboxProperty_;
}
// STUFF
};
class Component {
// PS. I tend to put my simple friend class definitions.
// inline within the class. They are after all part
// of the classes public interface and tightly bound
// to the implementation of the class.
friend std::ostream& operator<<(std::ostream& out, const Component& component) {
return out << component.properties_;
}
// STUFF
};Advantage of doing it this way is you can get rid of this getter methods.
Code Snippets
class ComponentProperties {
friend std::ostream& operator<<(std::ostream& s, ComponentProperties const& d) {
return d.print(s);
}
virtual std::ostream& print(std::ostream& s) const {
return s << componentProperty_;
}
// STUFF
};
class TextboxProperties: public ComponentProperties {
virtual std::ostream& print(std::ostream& s) const {
return ComponentProperties::print(s) << ", " << textboxProperty_;
}
// STUFF
};
class Component {
// PS. I tend to put my simple friend class definitions.
// inline within the class. They are after all part
// of the classes public interface and tightly bound
// to the implementation of the class.
friend std::ostream& operator<<(std::ostream& out, const Component& component) {
return out << component.properties_;
}
// STUFF
};Context
StackExchange Code Review Q#42335, answer score: 6
Revisions (0)
No revisions yet.