Using static cast would probably result in something like this:
// This does not prevent a possible type overflow
const char char_max = -1;
int i = 48;
char c = (i & char_max);
To prevent possible type overflow you could do this:
const char char_max = (char)(((unsigned char) char(-1)) / 2);
int i = 128;
char c = (i & char_max); // Would always result in positive signed values.
Where reinterpret_cast would probably just directly convert to char, without any cast safety.
-> Never use reinterpret_cast if you can also use static_cast.
If you're casting between classes, static_cast will also ensure, that the two types are matching (the object is a derivate of the cast type).
If your object a polymorphic type and you don't know which one it is, you should use dynamic_cast which will perform a type check at runtime and return nullptr if the types do not match.
IF you need const_cast you most likely did something wrong and should think about possible alternatives to fix const correctness in your code.