1

In the following class definition:

#include<iostream> 

class Test 
{ 
private: 
  int x; 
  int y; 

public: 
  Test(int x = 0, int y = 0) { this->x = x; this->y = y; } 
  Test &setX(int a) { x = a; return *this; } 
  Test &setY(int b) { y = b; return *this; } 
  void print() { cout << "x = " << x << " y = " << y << endl; } 

}; 

I don't understand why we should put an * in front of this in the setX or setY functions. I know this is a pointer to the current object and the * returns the pointed object, but since there is a & in the functions' return values, which means that the function returns a reference to a Test object. Then, shouldn't the return variable also be a reference (that is a pointer), like this:

Test &setX(int a) { x = a; return this; }

?

As an alternative, I believe

Test setX(int a) { x = a; return *this; }

would also be correct because the return value is not a pointer, but the pointed object, which of type Test (and not of type pointer to Test: Test&).

Why, if it's the case, are they not correct?

Evg
  • 25,259
  • 5
  • 41
  • 83
some_math_guy
  • 333
  • 1
  • 8
  • 2
    _Then,shouldn't the return variable also be a reference (that is a pointer)._ A pointer is not a reference – Thomas Sablik Dec 09 '19 at 18:57
  • 1
    And a reference is not a pointer. – Mooing Duck Dec 09 '19 at 18:57
  • 1
    `this` is a pointer to the object, so it has type `Test *`. You cannot return it as `Test &`. If you use `return *this;`, you can return it as `Test &` or `Test`, but the second will return a new copy of the object instead of a reference to the same object. – jdehesa Dec 09 '19 at 18:57
  • I come from C and function can return by value or by reference, the later being a pointer, isn't it? – some_math_guy Dec 09 '19 at 18:59
  • In C there are no references. Some people call it "call-by-reference" but technically it's call-by-pointer or call-by-address and it's the same as call-by-value. The same is true for return values. Pointers and references are not the same. https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_reference – Thomas Sablik Dec 09 '19 at 18:59
  • @juancarlosvegaoliver -- In `C`, everything is passed or returned by value, including pointers. – PaulMcKenzie Dec 09 '19 at 19:03
  • 1
    `this` is a pointer to the object. `*this` is *the object* (obtained by dereferencing the pointer). The function returns a *reference to the object*, so you have to dereference the pointer to get what the return value needs. – Jesper Juhl Dec 09 '19 at 19:09
  • @PaulMcKenzie how can I prove that? It's kind of subtle, because pointers simulate pass by reference – some_math_guy Dec 09 '19 at 20:21
  • There is nothing to "prove". Everything in `C` is passed by value. That's how the language works. – PaulMcKenzie Dec 09 '19 at 20:22

4 Answers4

3

Then,shouldn't the return variable also be a reference (that is a pointer), like this:

Test &setX(int a) { x = a; return this; }

That would be a compiler error. this is a pointer. It cannot be converted to the reference type Test&. However, when you dereference this, it can be used as the reference type Test&.

 This& temp = this;   // An error.
 This& temp = *this;  // OK

Reimagine your function as:

Test &setX(int a)
{
   x = a;
   // This& temp = this;  // Error
   This& temp = *this;    // OK
   return temp;
}
Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

The part that concerns the difference between this and *this has been addressed in other answers. Let's take a look at the difference between returning Test and Test&.

I believe Test setX(int a) { x = a; return *this; } would also be correct

Consider the chain:

t.setX(1).setY(2);

If set_ returns a copy of *this (Test setX(int);), and not a reference (Test& setX(int);), chaining will not work, because setY will modify that copy, not t itself. After ; the copy will be destroyed and the result of assignment y = 2 will be lost.

If you don't need chaining, set_ can simply be made void:

void setX(int a) { x = a; }
Evg
  • 25,259
  • 5
  • 41
  • 83
1

There's two parts:

Test& setX(int a); is a function setX returning a reference to a Test. You can think of it like a pointer that's dereferenced everywhere it's used.

So, you can't return a pointer, you have to return a Test&, i.e. *this

tstenner
  • 10,080
  • 10
  • 57
  • 92
  • In C, does the same concept of reference in C++ exist?. I am used to this symbol "&", being used to return addresses when applied to variables. But Test& is not an address , is it? – some_math_guy Dec 09 '19 at 19:54
  • 1
    C has no references, but is has pointers. The `*` symbol, when applied to types means "that, but a pointer-to". When applied to variables, it means "derefence that pointer". – tstenner Dec 10 '19 at 10:13
  • 1
    In C++, the `&`, when applied to types mean "that, but a reference-to", when applied to variables it means "address of that". – tstenner Dec 10 '19 at 10:14
1

In C++ you can't initialise a reference with a pointer. For this reason this (which you correctly said is a pointer) is dereferenced.

Also keep in mind that pointer and reference are not the same! A pointer contains an address, can be NULL and can be reassigned. A reference is "another name for an object", can't be NULL and can't be reassigned.