this's introduction into the language predates references -- it's a pointer because at the time it had to be, and it was never changed.

Changing it to a reference would be of little value:

  • Objects that manage their own lifetimes are not uncommon -- for instance, objects that delete this; when a reference count reaches zero -- this is particularly common in COM.
  • Assignment operator overloads (const T& operator=(const T&)) often check for self-assignment (that is, saying something such as:
    T a;
    a = a;
    
    ). Self-assignment rarely happens that obviously; it normally happens when variables are aliased. Now, one might naively think that the self-assignment test could look like:
    const T& operator=(const T& rhs)
    {
        if(*this == rhs)
        {
            return *this;
        }
    }
    
    but that has a problem. The minor problem is that some classes have no suitable operator==, so the test is impossible. The major problem is when rhs is actually a subclass of T rather than a T -- the equality test will do the wrong thing, as it will use T::operator==() rather than subclass::operator==(). The solution is to compare the addresses of this and rhs. If the addresses are identical, self-assignment is being attempted. If they're not, you can rest assured that they are different objects.
  • Many data structures (particularly node-based ones) use pointers to nodes, and they use this for this reason.

To summarize: this is not a reference because it predates references. It could have been changed into a reference, but the utility of this is questionable; many widely used constructs make use of its being an address. Making it a reference would save a little typing in some cases, but add a bit of typing in other cases -- there is no clear benefit.

Of course, if it really offends you so much you can always #define self (*this) and use self as you would otherwise use this.