moc is short for Meta Object Compiler. It tries to implement the major feature of Objective-C, messaging, with the means of C++ and in a somewhat more typesafe way.
To achive that, moc creates C++ source from your .moc files that builds a singleton QMetaObject for your class. The QMetaObject will maintain for your class a number of hash tables. One hash table, called slot table, is a number of public functions that can be called by their name. Another hash table, called properties table, is a number of public instance variables, that can be accessed by their name. Finally, a hash table, called signal table, contains a list of slot names that are called when the signal is raised. A signal entry can be connected to any number of slots with a compatible function signature.
Why is that cool?
Having a meta objects is cool.
A meta object means that a class instance can describe itself at runtime. It can enumerate its methods and instance variables, it can determine its class.
This makes all kinds of generic object handling easier. For example, having a meta object that lists a classes methods allows you to create surrogate objects that transparently stand in for the instance of an object, claim to implement the required methods and forward the actual function calls to a remote instance of that object. In Objective-C, NeXT implemented their version of Corba that way, in Qt some people are just starting to experiment with this. If the meta object had a complete listing of the objects methods and variables, it would even be possible to implement generic serialization and unserialization methods for objects, as available in Nextstep. Unfortunately, in moc we only have incomplete descriptions of a class in our meta objects: Only slots and properties are listed, but regular C++ functions and variables are not.
Calling methods by name is cool, too.
It means that you do not call "the second function in the virtual method table of that class" as in C++, but "the function named display, whatever that is, and in whichever position in the VMT it is".
In practice it means that you never experience the fragile superclass problem with Qt or Objective-C: because a superclass changed, you have to recompile all derived classes and all modules that used to Superclass or any of the recompiled derived classes.
It also means that you determine the actual function address that is being called at runtime, meaning that you have pretty much independent modules.