Avoiding casts in abstract types 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 &lt;iostream&gt;
#include &lt;string&gt;

// 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&amp; properties ):
    properties_( properties ) {  }

  virtual ~Component(  ) {  }

protected:
  ComponentProperties&amp; properties_;
};

class Textbox : public Component {
public:
  Textbox( TextboxProperties&amp; properties ):
    Component( properties ) {  }

  // overload &lt;&lt; purely for displaying properties.
  friend std::ostream &amp; operator &lt;&lt; ( std::ostream&amp; out, const Textbox&amp; textbox );
};

std::ostream &amp; operator &lt;&lt; ( std::ostream&amp; out, const Textbox&amp; textbox ) {  
  return out &lt;&lt; textbox.properties_.getComponentProperty(  ) &lt;&lt; ", "
             &lt;&lt; dynamic_cast&lt; TextboxProperties&amp; &gt;( textbox.properties_ ).getTextboxProperty(  );
}

int main(  ) {
  TextboxProperties properties( "PropertyOne", "PropertyTwo" );
  Textbox textbox( properties );

  std::cout &lt;&lt; textbox &lt;&lt; std::endl;
  return 0;
}
The best solution is to make ComponentProperties know how to print itself.

 class ComponentProperties {
     friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; s, ComponentProperties const&amp; d) {
         return d.print(s);
     }
     virtual std::ostream&amp; print(std::ostream&amp; s) const {
         return s &lt;&lt; componentProperty_;
     }
     //  STUFF
 };

 class TextboxProperties: public ComponentProperties {
     virtual std::ostream&amp; print(std::ostream&amp; s) const {
         return ComponentProperties::print(s) &lt;&lt; ", " &lt;&lt; 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&amp; operator&lt;&lt;(std::ostream&amp; out, const Component&amp; component) {  
          return out &lt;&lt; component.properties_;
      }
      // STUFF
  };


Advantage of doing it this way is you can get rid of this getter methods.