Avoiding down-casts in C++