Re: The merits of dynamic_cast<>()
On Sep 15, 4:41 pm, Sudarshan Narasimhan <sudarshan...@gmail.com>
wrote:
On Sep 15, 4:07 pm, Sam <s...@email-scan.com> wrote:
Leslaw Bieniasz writes:
Hi,
I am curious what is the current opinion about the merits of using
dynamic_cast<>(). I remember reading somewhere several years ago
that it was considered a bad practice to use the dynamic casting,
Bullshit.
and that in cases when such a need arises, one should think about
redesigning the code. My question is how to do it.
The situation that I have is as follows:
I have a base class A, and a number of derived classes B, C, etc.
The problem is that although the classes have a lot of common
functionality (contained in A), there are also some specific
features (new methods) added to B, C, etc.
But, since there is a common functionality, it is convenient to
keep pointers to the various objects as pointers to A, in a common
container. This implies that whenever I need to access the common
functionality, I can use pointers to A, but if I need the specific
features, I have to cast from the pointer to A, to pointers to derive=
d
classes. Is this OK, or there are ways to implement the same
thing without using dynamic_cast<>() ?
Define all methods as virtual methods in your base class, with the base
class's skeleton implementation returning an appropriate error code, or
throwing an appropriate exception, then define the appropriate methods =
in
each one of your derived classes.
Although this is not the case where one would use dynamic_cast<>, there=
's
nothing wrong, per se, with this operator.
application_pgp-signature_part
< 1KViewDownload
What you have described is a very common situation.
If derived classes have new functionality which is not related to the
base class, then it is a violation of the public inheritance "is a"
paradigm. If a set of derived classes alone implement this new
functionality, then it makes sense to have a new class derive from A
(which defines a virtual method that such sub classes need to
implement) and the classes implementing this functionality derive from
this new class. It makes the design that much cleaner.
I can provide an example.
class Mammals {
virtual move();
virtual eat();
virtual breed();
string name;
}; // Fine for humans, cows and goats
How about the mammals dolphins, whales. A swim method needs to be
defined for them. So if there were a function that calls this method,
void swim(Mammals &m)
{
// Need a dynamic cast here
m->swim(); // You need a dynamic cast here if you are passing a
"Mammal"
}
solution:
class AquaticMammals : public Mammals {
virtual void swim(); //
}
class dolphin: public AquaticMammals {
};
Now you can pass AquaticMammals without using a dynamic cast.
void swim(AquaticMammals &m)
{
m->swim(); // No need for a cast, also it realistically repres=
ent
the relationship
}
You can check if this helps.
If you cannot for some reason redefine the classes, add these new
functionalities as virtual methods in the base class, provide a
default implementation to throw an error(catch it at run time to see
any calls to inappropriate derived classes). Only in the required
classes, redefine these functions to provide desired implementation.
However, approach 1 is desirable.
Also i would add that if you need to pass a base type to call a "new
functionality" added to a "few" derived classes, it is not really
correct to pass a base type in the first place. You need a subtype as
indicated. But if all your derived classes need to implement this
functionality, make it (pure)virtual in the base class and redefine in
all the derived clasees. IN either case you dont need a dynamic_cast.
And cases where you cannot perhaps avoid a dynamic_cast<> are: if you
need to implement a handler which receives a message; it could be any
type of msg, all you know is it is of a base type "class Msg". And if
you have to do different things for different types of messages(again
this indicates a missing design consideration but lets just say you
cant change the Msg related code); you got to use dynamic_cast<>. But
its really great if you can restrict the usage of dynamic_cast<> to
just that.