Voyons d'abord pourquoi vous voudriez avoir une classe de base en premier lieu. Je peux penser à plusieurs raisons différentes:
- Pour prendre en charge des opérations génériques ou des collections qui fonctionneront sur des objets de tout type.
- Pour inclure diverses procédures communes à tous les objets (comme la gestion de la mémoire).
- Tout est un objet (pas de primitifs!). Certains langages (comme Objective-C) ne l'ont pas, ce qui rend les choses assez compliquées.
Ce sont les deux bonnes raisons pour lesquelles les langages de la marque Smalltalk, Ruby et Objective-C ont des classes de base (techniquement, Objective-C n'a pas vraiment de classe de base, mais à toutes fins utiles, il en a).
Pour # 1, le besoin d'une classe de base qui unifie tous les objets sous une seule interface est évité par l'inclusion de modèles dans C ++. Par exemple:
void somethingGeneric(Base);
Derived object;
somethingGeneric(object);
n'est pas nécessaire, lorsque vous pouvez maintenir l'intégrité du type tout au long du polymorphisme paramétrique!
template <class T>
void somethingGeneric(T);
Derived object;
somethingGeneric(object);
Pour le n ° 2, alors qu'en Objective-C, les procédures de gestion de la mémoire font partie de l'implémentation d'une classe et sont héritées de la classe de base, la gestion de la mémoire en C ++ est effectuée en utilisant la composition plutôt que l'héritage. Par exemple, vous pouvez définir un wrapper de pointeur intelligent qui effectuera le comptage de références sur des objets de tout type:
template <class T>
struct refcounted
{
refcounted(T* object) : _object(object), _count(0) {}
T* operator->() { return _object; }
operator T*() { return _object; }
void retain() { ++_count; }
void release()
{
if (--_count == 0) { delete _object; }
}
private:
T* _object;
int _count;
};
Ensuite, au lieu d'appeler des méthodes sur l'objet lui-même, vous appelleriez des méthodes dans son wrapper. Cela permet non seulement une programmation plus générique: cela vous permet également de séparer les préoccupations (car idéalement, votre objet devrait être plus préoccupé par ce qu'il doit faire, que par la façon dont sa mémoire doit être gérée dans différentes situations).
Enfin, dans un langage qui a à la fois des primitives et des objets réels comme C ++, les avantages d'avoir une classe de base (une interface cohérente pour chaque valeur) sont perdus, car vous avez alors certaines valeurs qui ne peuvent pas se conformer à cette interface. Afin d'utiliser des primitives dans ce genre de situation, vous devez les transformer en objets (si votre compilateur ne le fait pas automatiquement). Cela crée beaucoup de complications.
Donc, la réponse courte à votre question: C ++ n'a pas de classe de base car, ayant un polymorphisme paramétrique via des modèles, il n'en a pas besoin.