4
#include <iostream>
using namespace std;

class Base{
    public:
    virtual void f(){
        std::cout << "Base\n";
    }
};

class Derived1 : public Base{
    public:
    void f(){
        std::cout << "Derived1\n";
    }

};

class Derived2 : public Base{
    public:
    void f(){
        std::cout << "Derived2\n";
    }
};




int main() {
    Derived1 d1;
    Derived2 d2;

    Base& ref = d1;
    ref.f();
    ref = d2;
    ref.f();

    return 0;
}

It is said that the reference cannot be reassigned. Here, the compiler accept this code and output is not understandable for me. Output:

Derived1 Derived1

So, what does mean ref = d2; in fact?

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
Gilgamesz
  • 4,727
  • 3
  • 28
  • 63
  • 3
    `ref = d2` means `d1 = d2`. – Kane Mar 16 '16 at 11:07
  • You may want to see http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper – Humam Helfawi Mar 16 '16 at 11:20
  • The way to think about this is that assignment, and *any* expression evaluation for that matter, happens on *values*. References are never values; they're only ever the types of variables. The *value* obtained from a reference variable is the object which is being referenced. – Kerrek SB Mar 16 '16 at 11:23

2 Answers2

5

What ref = d2 actually did was assign the value of d2 to d1 - however, it's still d1 which is referred to by ref. Because d1 is still referred to, invoking ref.f still prints Derived1.

Suppose you add a data value v to your base class - set it to 1 in d1 and 2 in d2. Change your implementations of f to print v. You get something like:

#include <iostream>
using namespace std;

class Base{
    public:
    int v;

    virtual void f(){
        std::cout << "Base : v=" << v << "\n";
    }
};

class Derived1 : public Base{
    public:
    void f(){
        std::cout << "Derived1 : v=" << v << "\n";
    }

};

class Derived2 : public Base{
    public:
    void f(){
        std::cout << "Derived2 : v=" << v << "\n";
    }
};

int main() {
    Derived1 d1;
    d1.v = 1;
    Derived2 d2;
    d2.v = 2;

    Base& ref = d1;
    ref.f();
    ref = d2;
    ref.f();

    return 0;
}

When run this will print:

Derived1 : v=1
Derived1 : v=2

Hopefully this makes it a bit clearer.

Best of luck.

2

References can't be reassigned. They work like aliases to variables.

ref = d2 calls assign operator of Base class and copies Base part of Derived2 d2 variable to Derived1 d1.

Elohim Meth
  • 1,777
  • 9
  • 13