Casting a base-class pointer/reference to a derived-class pointer/reference is commonly referred to as downcasting which can only be done
using an explicit cast.
However, the use of static_cast for such a cast is unsafe because it doesn’t do any runtime check.  If the cast memory doesn’t
contain an object of the expected derived type, your program enters the undefined behavior territory.
If your object is polymorphic, you might prefer using dynamic_cast instead, as it allows safe downcasting by performing a run-time
check:
  -  If the cast memory contains an object of the expected derived type, the check succeeds. The result of the
  dynamic_castpoints/refers to the derived object.
-  If the cast memory doesn’t contain an object of the expected derived type, the check fails. If the dynamic_castis used on a
  pointer,nullptris returned. If it was used on a reference,std::bad_castis thrown.
This rule raises an issue when static_cast is used for downcasting.
Noncompliant code example
struct Shape {
  virtual ~Shape();
  // ...
};
struct Rectangle : public Shape {
  double width;
  double height;
};
struct Circle : public Shape {
  double radius;
};
double computeArea(const Shape* shape) {
  const auto* rectangle = static_cast<const Rectangle*>(shape); // Noncompliant
  return rectangle->width * rectangle->height;
}
Compliant solution
struct Shape {
  virtual ~Shape();
  // ...
};
struct Rectangle : public Shape {
  double width;
  double height;
};
struct Circle : public Shape {
  int radius;
};
double computeArea(const Shape* shape) {
  if(const auto* rectangle = dynamic_cast<const Rectangle*>(shape)) { // Compliant
    return rectangle->width * rectangle->height;
  }
  return 0;
}