As the project progresses you may add more and more classes down the class hierarchy. The need to add a specialised function with runtime binding, may mean adding a pure virtual function to the base class.
But this will probably cause changes to other derived classes, not necessarily sensible changes.
If you want to utilise advantages of polymorphism, you need to plan the class hierarchy to make sure that changes will not go too far.
If you want to use the concept of polymorphism, consider only classes which can be processed in a uniform way. You may need to stop extension of the class hierarchy at certain stage.
You want to add a method fireGuns() to Frigate.
However, it is not declared in the base abstract class Boat.
We can add a pure virtual method fireGuns() to the class Boat, but how does fireGuns() make sense to other classes in the hierarchy?