Search code examples
c#c++dynamic-cast

Why is dynamic_cast considered bad practice in C++?


I know there is quite a few questions along these lines already, but I still don't understand. Take for example:

class Projectile
{
   public:
    virtual void OnCollision(Projectile& other);

   private:
    Vector position;
    Vector velocity;
};
class Bullet : Projectile
{
    // We may want to execute different code based on the type of projectile
    // "other" is.
    void OnCollision(Projectile& other) override;
};
class Rocket : Projectile
{
    // If other is a bullet, we might want the rocket to survive the collision,
    // otherwise if it's a rocket, we may want both to explode.
    void OnCollision(Projectile& other) override;
};

I don't understand how this example could be done without dynamic_cast. We can't rely on just a polymorphic interface, because that will only provide us with information about one object in this case. Is there a way this can be done without dynamic_cast?

Also, why isn't dynamic casts considered bad practice in C#? They're used ALL the time throughout event handlers and non-generic containers. A lot of what can be done in C# relies on casts.


Solution

  • In this specific example, I would have added a protected method:

    protected:
       virtual int getKickassNess() = 0;
    
    // Bullet:
       int getKickassNess() override { return 10; }
    // Rocket:
       int getKickassNess() override { return 9001; }  // over 9000!
    
    void Bullet::OnCollision(Projectile& other)
    {
       if (other.getKickassNess() > this->getKickassNess())
          // wimp out and die
    }
    

    IMO Bullet and Rocket should not know that each other exist. Putting in these kinds of knows-about relationships often make things difficult, and in this specific case I can imagine it causing messy cyclic include issues.