1

As noted in this answer:

high reliance on dynamic_cast is often an indication your design has gone wrong.

What I'd like to know is how can I call a custom function in a derived class, for which there is no same-name function in the base class, but do so using a base class pointer and perhaps without dynamic_cast if in fact there is a better way.

If this function was a virtual function defined in both, that's easy. But this is a unique function only in the derived class.

Perhaps dynamic_cast is the best way afterall?

Community
  • 1
  • 1
johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • 7
    Well it's the fact that you want to do what you want to do that is the sign your design could do with a rework. If you *need* to do it, use `dynamic_cast`. – Joseph Mansfield May 15 '13 at 13:46
  • 3
    Maybe it's just me, but I suspect your desing has gone slightly wrong. – jrok May 15 '13 at 13:47
  • Out of interest, what sort of scenario would require you to do this? – Muckle_ewe May 15 '13 at 13:49
  • If you really want to do that, you should ask yourself if at the point you want to do that you are really handling the correct type. If the code is designed to work with the base class, then you should work with the base class, and if you all over the place have to ask "is it maybe this type, then do that" this is just the wrong type level you work at. – PlasmaHH May 15 '13 at 13:50
  • @Muckle_ewe: The most likely scenario is if you use base-class pointers to navigate to an object, and then need to do something that's not exposed via the base class. RTTI is one option to solve that problem, others being a fat base class, the visitor pattern, or a redesign of the navigation scheme. – Mike Seymour May 15 '13 at 14:46

3 Answers3

5

In order to call a function of Derived class you have to obtain a pointer to derived class. As an option (depending on situation) you may want using static_cast instead of dynamic, but as you said:

it is often an indication your design has gone wrong

Also, sometimes I think it's ok to use casts. When I was designing a GUI library for a game it has a base class Widget and lots of subclasses. An actual window layout was made in an editor and later some Loader class was inflating this layout. In order to fill widgets from the layout with actual specific for each widget data (game related) I made a method for quering widget's child from a widget. This function retuned Widget* and then I dynamic_casted it to actual type. I have not found a better design for this.

Later I also found that GUI system on Android works the same way

Andrew
  • 24,218
  • 13
  • 61
  • 90
  • Interesting, thanks. I have added a new question that goes into greater detail about exactly what I need to achieve. http://stackoverflow.com/questions/16577697/struggling-with-design-decision-regarding-polymorphic-member – johnbakers May 16 '13 at 01:42
1

What I'd like to know is how can I call a custom function in a derived class ... without dynamic_cast if in fact there is a better way

As indicated in the quote, it's a design issue, not an implementation issue. There's no "better way" to call that function; the "better way" is to redesign your types so that subtypes don't need to add functionality to their parents. By doing so, your types satisfy (a common interpretation of) the Liskov Substitution Principle, and are easier to use since users don't need to know about the subtypes at all.

If it's impossible or unreasonably difficult to redesign the types in such a way, then perhaps you do need RTTI. The advice doesn't say "All use of ...", just "High reliance on ...", meaning that RTTI should be a last resort, not a default approach.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

This is more like an option then a real answer, so don't stone me to death.

class Derived;

class Base
{
public:

   virtual Derived * getDerived()const
   {
       return NULL;
   }
};

class Derived : public Base
{
public:

   virtual Derived * getDerived()const
   {
       return this;
   }
};

I guess you get the picture...

P.S. Mike Seymour, thanks :-)

user1764961
  • 673
  • 7
  • 21
  • 1
    @DyP: It can be a useful hack to access a small number of potential derived classes from the base class without full-blown RTTI; although you'd need to return the actual subtype rather than `void*` for it to be even vaguely safe. It doesn't scale very well, though. – Mike Seymour May 15 '13 at 14:15
  • @MikeSeymour You still had to cast the `void*` to `Derived*`, so I don't see how this is different from `static_cast(this)` (or `reinterpret_cast`) within a function member of `Base`. – dyp May 15 '13 at 14:31
  • @DyP: Indeed, which is why I said that it should return the actual subtype rather than `void*` for it to be even vaguely safe. – Mike Seymour May 15 '13 at 14:32