Why Is 'This' a Pointer and Not a Reference

Why is 'this' a pointer and not a reference?

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.

When to use references vs. pointers

Use reference wherever you can, pointers wherever you must.

Avoid pointers until you can't.

The reason is that pointers make things harder to follow/read, less safe and far more dangerous manipulations than any other constructs.

So the rule of thumb is to use pointers only if there is no other choice.

For example, returning a pointer to an object is a valid option when the function can return nullptr in some cases and it is assumed it will. That said, a better option would be to use something similar to std::optional (requires C++17; before that, there's boost::optional).

Another example is to use pointers to raw memory for specific memory manipulations. That should be hidden and localized in very narrow parts of the code, to help limit the dangerous parts of the whole code base.

In your example, there is no point in using a pointer as argument because:

  1. if you provide nullptr as the argument, you're going in undefined-behaviour-land;
  2. the reference attribute version doesn't allow (without easy to spot tricks) the problem with 1.
  3. the reference attribute version is simpler to understand for the user: you have to provide a valid object, not something that could be null.

If the behaviour of the function would have to work with or without a given object, then using a pointer as attribute suggests that you can pass nullptr as the argument and it is fine for the function. That's kind of a contract between the user and the implementation.

Why is the 'this' keyword not a reference type in C++

See Stroustrup's 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".

Why the request is a pointer variable? Why not a reference variable?

Duplicate of In Go HTTP handlers, why is the ResponseWriter a value but the Request a pointer?

Mainly the ResponseWriter is an interface (you may want to understand more about interfaces, just in case you haven't gone over it). Just to add, the request is a pointer to a struct - there's no point in having a copy of the request struct (which happens when passed by value), so it's not passed as a struct (think of it esp. when you pass it downstream to other functions, you can just pass this down directly)

Difference between pointer to a reference and reference to a pointer

First, a reference to a pointer is like a reference to any other variable:

void fun(int*& ref_to_ptr)
{
ref_to_ptr = 0; // set the "passed" pointer to 0
// if the pointer is not passed by ref,
// then only the copy(parameter) you received is set to 0,
// but the original pointer(outside the function) is not affected.
}

A pointer to reference is illegal in C++, because -unlike a pointer- a reference is just a concept that allows the programmer to make aliases of something else. A pointer is a place in memory that has the address of something else, but a reference is NOT.

Now the last point might not be crystal clear, if you insist on dealing with references as pointers. e.g.:

int x;
int& rx = x; // from now on, rx is just like x.
// Unlike pointers, refs are not real objects in memory.
int* p = &x; // Ok
int* pr = ℞ // OK! but remember that rx is just x!
// i.e. rx is not something that exists alone, it has to refer to something else.
if( p == pr ) // true!
{ ... }

As you can see from the above code, when we use the reference, we are not dealing with something separated from what it refers to. So, the address of a reference is just the address of what it refers to. Thats why there is no such thing called the address of the reference in terms of what you are talking about.

In Go, is a structure pointer not a reference type?

pnum, in main, is an actual variable: a box, floating in memory, containing a pointer of type *Num.

 0x40c138
+--------+
| *---|--->
+--------+

To what does pnum point? Well, Num{i: 3} created an unnamed variable, floating in memory somewhere. We haven't printed it. I modified your Playground example to add one more fmt.Printf call to find out:

main type [**main.Num] : 0x40c138
pnum points to [*main.Num] : 0x40e020

or:

 0x40c138       0x40e020
+--------+ +--------+
| *---|---> | i: 3 |
+--------+ +--------+

Now let's move on: main calls pointer, passing to it the value stored in pnum—the 0x40c138 value which lets the computer find the box holding the unnamed instance holding i=3. This value is stored in memory somewhere. Where is that somewhere? Why, it's the number you printed, because you print &ip. Fortunately the Playground is very deterministic, so it's also the one I printed:

pointer type [**main.Num] : 0x40c148

So we can add another box to our drawing:

 0x40c138       0x40e020
+--------+ +--------+
|0x40e020|---> | i: 3 |
+--------+ +--------+
^
0x40c148 |
+--------+ |
|0x40e020|---------+
+--------+

Now pointer returns, discarding the box at 0x40c148 that holds 0x40e020, and you call pointerpointer, passing &pnum as a value. Function pointerpointer now runs with a box at some location. Where is that location? We don't know; we never print it. We do print what's in the box at that location, and what's in the box is 0x40c138:

 0x40c138       0x40e020
+--------+ +--------+
|0x40e020|---> | i: 3 |
+--------+ +--------+
^
|
????????
+--------+
|0x40c138|
+--------+

We can add one more fmt.Printf to the program to find where this last box actually is in memory and run again:

pointerpointer's &ip is [***main.Num] : 0x40c150

so replace the eight question marks with 0x40c150.

The overall rule here is simple enough: Every variable has some existence somewhere, unless the compiler can optimize it away. Taking the address of the variable, with &x, tends to prevent the compiler from optimizing the variable itself away. The type of &x is pointer to ___ where the blank is the type of x. The value of &x is the address of the variable.

In this case, you

  • made an anonymous (unnamed) Num instance,
  • took its address (forcing the compiler to put it into memory somewhere), and
  • set a variable pnum to that value

(all in the first line of main). Then you took the address of pnum itself, which means pnum also has to live somewhere in memory. Those are the two boxes we drew initially. You printed that address's type and value on your second line.

You then passed the value stored in pnum to func pointer, which stored the value in a variable. So that created another, separate variable, which has its own address.

Without worrying about what function pointer did, you then passed the address of pnum to func pointerpointer. This address is a value, and pointerpointer stored that value in a variable. This, too, created another separate variable.

Throughout all of this, the address of the anonymous Num with i=3 never moved. Neither did the address of pnum itself.

How is a reference and a pointer to an array different from each other and which one is preferable?

The size of reference is int*10 vs size of pointer which is 8.

A reference is an alias, so the size of reference is int*10, which is the same as sizeof(arr)

How are these two different and is there a standard practice as to
when to use a reference or a pointer?

Prefer to use reference when you don't need to control the lifetime of the object. When you find that reference can't meet your requirement then we have to use pointers.

Reference vs pointer:

  • reference must be inited
  • pointer doesn't have to be inited
  • reference can be dangling, pointers can be dangling too
  • the pointer which controls the ownership of resource needs to be deleted to avoid resource leaking(We can use smart pointers to avoid it)

You may also read Google c++ style guide to get more information on choice of reference vs pointer

In C++, why isn't the this keyword a reference?

The this concept was introduced before the reference concept was. At the time, this had to be a pointer.Source



Related Topics



Leave a reply



Submit