Oui, "moralement" je sais pas si ça peut avoir un usage propre (où il y aurait des classes héritées avec des fonctions non-virtuelles qui ont une sémantique vraiment différente), mais c'est utile parce que ça n'impose pas de passer par la virtual function table, et donc ça permet l'inlining... Si vector::size() était virtuelle (et donc non-inlinable), ça imposerait une grosse pénalité sur "for (size_t i=0; i<v.size(); i++)", parce qu'il faudrait non seulement appeler la fonction, mais en plus le faire à chaque tour de la boucle parce qu'on ne sait pas que la taille reste constante
Donc en gros c'est une optimisation de performance qui sert quand :
- on ne compte pas faire de classes dérivées
- on compte faire des classes dérivées, mais dont l'héritage ne sera pas public (d'ailleurs l'exemple de spectras a encore un bug, il n'hérite pas publiquement de la classe Base, donc il n'a pas le droit de passer de Derived* à Base*

) : ça permet par exemple de définir ta propre classe basée sur std::vector, mais avec des méthodes différentes
- on compte faire des classes dérivées et éventuellement redéfinir cette fonction, mais on sait que la fonction définie dans la classe de base sera toujours correcte (mais pas forcément optimale), par exemple
class Base {
bool is_enabled;
public:
bool enabled() const {
return is_enabled;
}
};
class Derived : public Base {
public:
Derived() : is_enabled(true) {}
bool enabled() const {
return true;
}
};