204

I was reading the answers to this question C++ pros and cons and got this doubt while reading the comments.

programmers frequently find it confusing that "this" is a pointer but not a reference. another confusion is why "hello" is not of type std::string but evaluates to a char const* (pointer) (after array to pointer conversion) – Johannes Schaub - litb Dec 22 '08 at 1:56

That only shows that it doesn't use the same conventions as other (later) languages. – le dorfier Dec 22 '08 at 3:35

I'd call the "this" thing a pretty trivial issue though. And oops, thanks for catching a few errors in my examples of undefined behavior. :) Although I don't understand what info about size has to do with anything in the first one. A pointer is simply not allowed to point outside allocated memory – jalf Dec 22 '08 at 4:18

Is this a constant poiner? – yesraaj Dec 22 '08 at 6:35

this can be constant if the method is const int getFoo() const; <- in the scope of getFoo, "this" is constant, and is therefore readonly. This prevents bugs and provides some level of guarantee to the caller that the object won't change. – Doug T. Dec 22 '08 at 16:42

you can't reassign "this". i.e you cannot do "this = &other;", because this is an rvalue. but this is of type T*, not of type T const . i.e it's a non-constant pointer. if you are in a const method, then it's a pointer to const. T const . but the pointer itself is nonconst – Johannes Schaub - litb Dec 22 '08 at 17:53

think of "this" like this: #define this (this_ + 0) where the compiler creates "this_" as a pointer to the object and makes "this" a keyword. you can't assign "this" because (this_ + 0) is an rvalue. of course that's not how it is (there is no such macro), but it can help understand it – Johannes Schaub - litb Dec 22 '08 at 17:55

My question is, why is this a pointer a not a reference? Any particular reason for making it a pointer?


Some further arguments why this being a reference would make sense:

  • Consider Item 1 from More Effective C++ : use references when it is guaranteed that we have a valid object i.e. not a NULL (my interpretation).
  • Furthermore, references are considered safer than pointers (because we can't screw the memory up with a stray pointer).
  • Thirdly, the syntax for accessing references (.) is a little bit nicer and shorter than accessing pointers (-> or (*)).
Community
  • 1
  • 1
Naveen
  • 74,600
  • 47
  • 176
  • 233
  • 1
    So people can do ugly hacks such as void foo::something() { if (this) stuff(); } } – paulm Dec 15 '13 at 22:20
  • 6
    @paulm What would this "hack" actually accomplish? Doesn't `this` always evaluate to `true`? – iFreilicht Jun 16 '14 at 13:15
  • foo* instance = nullptr; foo->something(); // Now if (this) == false – paulm Jun 16 '14 at 17:54
  • 6
    @paulm I don't think that's actually valid C++. Invoking methods on a nullptr to an object results in undefined behavior. – antred Aug 26 '14 at 12:48
  • Hmm are you sure about that? I've actually seen it in production code – paulm Aug 26 '14 at 13:13
  • 5
    @paulm Maybe it works in some cases, but imagine if the method was virutal. How could a v-table lookup be done with no object? – Jason C May 08 '15 at 18:11
  • I guess you'd crash in that case – paulm May 08 '15 at 23:50
  • 3
    @paulm If you've seen it in production code, abandon ship! That is UB. – Alice Sep 12 '15 at 18:00
  • 8
    I'm just gonna leave this here... (from MFC's afxwin2.inl): `_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }` – Christopher Oicles Oct 19 '15 at 21:22
  • Related question (not expecting an answer...): why is `this` a keyword, instead of an identifier which is pre-defined within member functions? The parser doesn't need it to be a keyword. Decades ago a co-worker was baffled by a syntax error he was getting, trying to compile some existing working C code. We both looked right at it and couldn't see it. But one of the structs had a field called `this` and he was using a C++ compiler (and, before the days of syntax highlighting). – greggo Nov 06 '19 at 22:14

3 Answers3

198

When the language was first evolving, in early releases with real users, there were no references, only pointers. References were added when operator overloading was added, as it requires references to work consistently.

One of the uses of this is for an object to get a pointer to itself. If it was a reference, we'd have to write &this. On the other hand, when we write an assignment operator we have to return *this, which would look simpler as return this. So if you had a blank slate, you could argue it either way. But C++ evolved gradually in response to feedback from a community of users (like most successful things). The value of backward compatibility totally overwhelms the minor advantages/disadvantages stemming from this being a reference or a pointer.

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
  • 5
    Well, it is also often useful for an object to get a reference to itself. I'd say that's a more common usage. Anyway, the main reason is like you said, references didn't exist when they created the 'this' pointer. – jalf Mar 14 '09 at 14:42
  • If 'this' was a reference, the main use of this would probably be 'this.member' instead of 'this->member', so you would not need the ampersand most of the time. – Jonathan Leffler Mar 14 '09 at 14:52
  • 1
    i completely agree with your first paragraph. and i think its main use is to get the address of the object. but why would that need a pointer? reference will do equally well and will do better for other cases like "this.foo" and "swap(this, bar)" – Johannes Schaub - litb Mar 14 '09 at 16:11
  • 1
    Also, early on C++ used assignment to this in a constructor in place of having an operator new. That's another important point in its evolution and a reason this is a pointer. – Omnifarious Jan 29 '10 at 16:28
  • 25
    And, if this were a reference, it would be difficult to overload `operator &` to do anything useful. There would have to be some special syntax for getting the address of this that wouldn't go through `operator &`. – Omnifarious Jan 29 '10 at 16:30
  • Actually, if `this` was a reference, and all other rules remained the same, you **couldn't** get a pointer using `&this`, since you can't apply the `&` operator on references. – conio Apr 06 '10 at 15:33
  • 11
    @conio - you might want to check that next time you're near a C++ compiler! :) Something like: `int n = 5; int &r = n; int *p = &r; std::cout << *p;` – Daniel Earwicker Apr 06 '10 at 15:39
  • 15
    @Omnifarious you could write `&reinterpret_cast(this);` to get the real address for overloading `operator&` (in fact, this is sort of what `boost::addressof` does). – Johannes Schaub - litb Jul 01 '10 at 22:57
  • 12
    Since it doesn't really make any sense for `this` to be null, it seems to me that a reference is really more fitting. – Ponkadoodle Feb 02 '12 at 03:30
  • @PravasiMeet - possibly a confusing use of the & symbol in your question! :) – Daniel Earwicker Nov 19 '15 at 13:45
  • @DanielEarwicker: I mean "and" not any operator. difference between return this and return *this. – Destructor Nov 19 '15 at 16:13
  • @JohannesSchaub-litb that would make it impossible for `operator&` to be constexpr – Aykhan Hagverdili Aug 11 '22 at 08:01
129

A little late to the party... Straight from the horse's mouth, here's what Bjarne Stroustrup has to say (which is essentially repeated in or taken from the "Design and Evolution of C++" book):

Why is "this" not a reference?

Because "this" was introduced into C++ (really into C with Classes) before references were added. Also, I chose "this" to follow Simula usage, rather than the (later) Smalltalk use of "self".

Waqar
  • 8,558
  • 4
  • 35
  • 43
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
9

In addition to the other answers, since Deducing this is in C++23, it will be possible to have a reference to the object for which a member function is called (instead of this pointer):

struct Foo {
  void bar(this Foo& self) {
    // self is a reference to Foo
  }
};

int main() {
  Foo foo;
  foo.bar();
}
oficsu
  • 140
  • 1
  • 5
  • Any language where you can write something like `this Self&& self` has some inherent problems... It seems that with all the new C++ revisions, they are adding more and more things that just fix problems with the language itself instead of adding functionality. `forward_like`, `declval`, `to_address`, `launder`, `start_lifetime_as`, `enable_if`, `void_t`, `destroying_delete_t`, `reference_wrapper`, `move_only_function`, `bind_front/back`, etc etc – tmlen Aug 29 '23 at 22:15