Why is there no base class in C++?

Solution 1:

The definitive ruling is found in Stroustrup's FAQs. In short, it doesn't convey any semantic meaning. It will have a cost. Templates are more useful for containers.

Why doesn't C++ have a universal class Object?

  • We don't need one: generic programming provides statically type safe alternatives in most cases. Other cases are handled using multiple inheritance.

  • There is no useful universal class: a truly universal carries no semantics of its own.

  • A "universal" class encourages sloppy thinking about types and interfaces and leads to excess run-time checking.

  • Using a universal base class implies cost: Objects must be heap-allocated to be polymorphic; that implies memory and access cost. Heap objects don't naturally support copy semantics. Heap objects don't support simple scoped behavior (which complicates resource management). A universal base class encourages use of dynamic_cast and other run-time checking.

Solution 2:

Let's first think about why you'd want to have a base-class in the first place. I can think of a few different reasons:

  1. To support generic operations or collections that will work on objects of any type.
  2. To include various procedures which are common to all objects (such as memory management).
  3. Everything is an object (no primitives!). Some languages (like Objective-C) don't have this, which makes things pretty messy.

These are the two good reasons that languages of the Smalltalk, Ruby and Objective-C brand have base-classes (technically, Objective-C doesn't really have a base-class, but for all intents and purposes, it does).

For #1, the need for a base-class that unifies all objects under a single interface is obviated by the inclusion of templates in C++. For instance:

void somethingGeneric(Base);

Derived object;
somethingGeneric(object);

is unnecessary, when you can maintain type integrity all the way through by means of parametric polymorphism!

template <class T>
void somethingGeneric(T);

Derived object;
somethingGeneric(object);

For #2, whereas in Objective-C, memory management procedures are part of a class's implementation, and are inherited from the base class, memory management in C++ is performed using composition rather than inheritance. For instance, you can define a smart pointer wrapper which will perform reference counting on objects of any 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;
};

Then, instead of calling methods on the object itself, you'd be calling methods in its wrapper. This not only allows more generic programming: it also lets you separate concerns (since ideally, your object should be more concerned about what it should do, than how its memory should be managed in different situations).

Lastly, in a language that has both primitives and actual objects like C++, the benefits of having a base-class (a consistent interface for every value) are lost, since then you have certain values which cannot conform to that interface. In order to use primitives in that sort of a situation, you need to lift them into objects (if your compiler won't do it automatically). This creates a lot of complication.

So, the short answer to your question: C++ doesn't have a base-class because, having parametric polymorphism through templates, it doesn't need to.

Solution 3:

The dominant paradigm for C++ variables is pass-by-value, not pass-by-ref. Forcing everything to be derived from a root Object would make passing them by value an error ipse facto.

(Because accepting an Object by value as parameter, would by definition slice it and remove its soul).

This is unwelcome. C++ makes you think about whether you wanted value or reference semantics, giving you the choice. This is a big thing in performance computing.