-1

For the following example:

#include <iostream>

using namespace std;

class Obj {
    public:
        Obj& operator=(const Obj& o) {
            cout << "Copy assignment operator called" << endl;
            return *this;
        }
};

Obj o;

int update(Obj& o) {
    o = ::o;
}

int main() {
    Obj o2;
    update(o2);
}

I get the result:

Copy assignment operator called

Why is a copy assignment used when assigning an object to a reference? Why isn't the reference just updated to point to the assigned object? Is this a matter of convention or is there a reason behind this?

johnnyodonnell
  • 1,838
  • 3
  • 16
  • 34
  • What else would you expect and why? There's no reference as target. – πάντα ῥεῖ Apr 19 '19 at 18:57
  • @πάνταῥεῖ I thought that maybe the reference (`Obj& o`) would be updated to point to `::o`. – johnnyodonnell Apr 19 '19 at 18:59
  • 1
    References cannot be re-seated - once initialised they always refer to the same object. –  Apr 19 '19 at 19:00
  • @NeilButterworth Gotcha, that answers my question. Thank you for the response! – johnnyodonnell Apr 19 '19 at 19:02
  • Think of it as assignment **through** a reference: the new value gets assigned to the object that the reference points at. – Pete Becker Apr 19 '19 at 19:21
  • @PeteBecker I'm not having difficulty understanding the behavior. My question is why does the language use this particular behavior when it could very easily use use a different behavior. [This answer](https://stackoverflow.com/questions/728233/why-are-references-not-reseatable-in-c/728272#728272) does a pretty good job of answering that question. – johnnyodonnell Apr 19 '19 at 21:23

1 Answers1

1

Assigning to a reference assigns to the object the reference refers to, not the reference itself. Thus, your update function is equivalent to:

o2 = ::o;
Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • I understand that now after seeing the results of this example. However, I'm curious as to why this is the case. – johnnyodonnell Apr 19 '19 at 19:01
  • It's to allow a function that takes a parameter by reference to mutate the original object. This is much more useful, in general, than reseating the reference would be. – Paul Sanders Apr 19 '19 at 19:04
  • @johnnyodonnell Because a reference is just another name for the object. References are not pointers. A pointer points to an object. A reference **is** the object, just with a different name. – Nikos C. Apr 19 '19 at 19:04
  • @NikosC. A reference is not a pointer, but it does point to an object. With the help of Neil's comment above, I was able to find [this](https://stackoverflow.com/a/728272/5832619). It looks like it could've been possible to reseat a reference, but it's precisely because of situations like this that Bjarne decided to not allow reseating of references. – johnnyodonnell Apr 19 '19 at 19:10
  • @johnnyodonnell It is not correct thinking that references point to objects, because everything points to objects, including non-references. The `n` for example in `int n;` points to a memory location that is interpreted as holding the bytes of an integer. The correct thinking for references is that they are another name for an object. They do not point to an object, in the same way that `n` in `int n;` does not point to an object. It **is** the object. – Nikos C. Apr 19 '19 at 19:42