Vamos primeiro pensar sobre por que você gostaria de ter uma classe base em primeiro lugar. Posso pensar em alguns motivos diferentes:
- Para dar suporte a operações genéricas ou coleções que funcionarão em objetos de qualquer tipo.
- Para incluir vários procedimentos que são comuns a todos os objetos (como gerenciamento de memória).
- Tudo é um objeto (sem primitivos!). Algumas linguagens (como Objective-C) não têm isso, o que torna as coisas muito confusas.
Estas são as duas boas razões pelas quais as linguagens da marca Smalltalk, Ruby e Objective-C têm classes base (tecnicamente, Objective-C não tem realmente uma classe base, mas para todos os efeitos e propósitos, ela tem).
Para o nº 1, a necessidade de uma classe base que unifique todos os objetos em uma única interface é evitada pela inclusão de modelos em C ++. Por exemplo:
void somethingGeneric(Base);
Derived object;
somethingGeneric(object);
é desnecessário, quando você pode manter a integridade do tipo por meio de polimorfismo paramétrico!
template <class T>
void somethingGeneric(T);
Derived object;
somethingGeneric(object);
Para o nº 2, enquanto em Objective-C, os procedimentos de gerenciamento de memória são parte da implementação de uma classe e são herdados da classe base, o gerenciamento de memória em C ++ é executado usando composição em vez de herança. Por exemplo, você pode definir um wrapper de ponteiro inteligente que fará a contagem de referência em objetos de qualquer tipo:
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;
};
Então, em vez de chamar métodos no próprio objeto, você chamaria métodos em seu invólucro. Isso não apenas permite uma programação mais genérica: também permite separar interesses (uma vez que, idealmente, seu objeto deveria estar mais preocupado com o que deveria fazer, do que como sua memória deveria ser gerenciada em diferentes situações).
Por último, em uma linguagem que possui objetos primitivos e reais como C ++, os benefícios de ter uma classe base (uma interface consistente para todos os valores) são perdidos, já que você tem certos valores que não podem estar em conformidade com essa interface. Para usar primitivos nesse tipo de situação, você precisa transformá-los em objetos (se o seu compilador não fizer isso automaticamente). Isso cria muitas complicações.
Então, uma resposta curta para sua pergunta: C ++ não tem uma classe base porque, tendo polimorfismo paramétrico por meio de templates, não precisa.