3

I have a parent class "base" and another class "derived" that inherits from "base".

"derived" has 1 method cH1.

if I do this:

base* b = new derived();

And I want to be able to do this:

b->cH1();

Obviously I can't and there are 2 solutions:

  • Either declare cH1 as pure virtual in base.
  • or do this:

    dynamic_cast<derived*>(b)->cH1();
    

Which one is a better practice?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Kam
  • 5,878
  • 10
  • 53
  • 97
  • 2
    Please turn off you caps-lock key; `PARENT` suggests that the name is a macro; `parent` is the usual usage. – Pete Becker Sep 14 '12 at 15:34
  • 1
    I'd say that the biggest problem in your head may be the use of the words "parent" and "child". Those are *really terrible* metaphors for base- and derived classes: A child, in common parlance, is not usually a parent, nor is it a more specific instance of a parent. A much better metaphor is "base class" and "derived class". – Kerrek SB Sep 14 '12 at 15:41
  • @PeteBecker and @KerrekSB: good suggestions. Moreover, I'd suggest to change `cH1` (kind of obscure and odd for a generic method name) to something like `m1` or `method1`. – Mr.C64 Sep 14 '12 at 16:13
  • Related: http://stackoverflow.com/questions/7200446/does-downcasting-defeat-the-purpose-of-polymorphism – SSJ_GZ Sep 14 '12 at 17:01

3 Answers3

7

If cH1 method semantically applies to base, then make it a base's method. Else, leave cH1 to derived, and use dynamic_cast. I think the semantics of your classes should drive your choice.

For example, if you have a base class Vehicle and derived classes Car, Motorbike, and Aircraft, a method like TakeOff() has a semantics compatible with Aircraft but not with Car or Motorbike, so you may want to make TakeOff() an Aircraft method, not a Vehicle method.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • I keep hearing this word and I never understood it :/ what do you mean by "semantically" applies to base? – Kam Sep 14 '12 at 16:06
  • 2
    @Kam: For example, if you have a base class `Vehicle` and derived classes `Car`, `Motorbike`, and `Aircraft`, a method like `TakeOff()` has a semantics compatible with `Aircraft` but not with `Car` or `Motorbike`, so you may want to make `TakeOff()` an `Aircraft` method, not a `Vehicle` method. – Mr.C64 Sep 14 '12 at 16:22
2

dynamic_cast is cleaner and more flexible, but a bit slower.

Remember when you use dynamic_cast to check the returned pointer for NULL.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • How is `dynamic_cast` cleaner and more flexible? There are cases where `dynamic_cast` may be justified, but from the information given, I don't think we can conclude that this is one of them. (In general, the use of virtual functions is cleaner.) – James Kanze Sep 14 '12 at 15:46
  • @JamesKanze, it's cleaner if the parent class isn't being cluttered with functions which aren't relevant to that class. I agree that we need more information of the class specifics to really know for sure. – Mark Ransom Sep 14 '12 at 15:57
2

First, in order to use dynamic_cast, base must have at least one virtual function.

Second, use of dynamic_cast is usually a sign of a design mistake. If derived is truly a child of base, then a derived object should be able to stand in wherever a base object is expected, and that usually means that base has virtual functions, either pure virtual or not, and that derived overrides some or all of them.

Without knowing what cH1 does, though, it's impossible to recommend an approach.

Kam
  • 5,878
  • 10
  • 53
  • 97
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • It's not always a mistake - sometimes you need a collection of objects which have some things in common but not others. – Mark Ransom Sep 14 '12 at 15:39
  • Use of `dynamic_cast` to the concrete class is almost always a mistake, but it's not that rare for a class (or a group of classes) to support an extended interface. In such cases, `dynamic_cast` is one way of supporting access to the extended interface. – James Kanze Sep 14 '12 at 15:45
  • I've added emphasis to the word **usually**, since it seems to have been overlooked. I didn't say it's always a mistake. – Pete Becker Sep 14 '12 at 15:56