register is mostly ignored these days, but it's supposed to hint to the compiler that you'd rather the variable be in a register instead of on the stack. Optimizers do such a good job these days that it's irrelevant now.
volatile tells the compiler to not assume that the value is only changed from the current thread, so it will always read the actual memory value instead of caching it between reads. It's useful for multi-threaded applications, but you're better off using OS primitives anyway (events, semaphores etc).
extern doesn't define the value, it only declares it. It's mostly used for exporting and importing functions from DLL's or shared libraries (.a). A side-effect also allows you to turn off name mangling for C++ using extern "C".
And explicit allows you to specify that a constructor has to be explicit, as opposed to implicit converting constructors (where you can write CMyClass val=10; if it has an implicit constructor that takes an int).