I was reading about NonVirtual Interface pattern: Herb Sutter is talking about why virtual function must be private in most of the case, protected in some case and never pub
I think this is because concrete class has concrete behavior. When deriving from it, you are committed to retain the same "contract", but the actual contract is defined by the specific implementation of the base class, and in reality will have many subtleties you will probably break without knowing.
Disclaimer: I am not an experienced developer; it is just a suggestion.