Re: reference question
junw2000@gmail.com wrote:
Hi,
My textbook says that: "Once defined, a reference cannot be reassigned
because it is an alias to its target. What happens when you try to
reassign a reference turns out to be the assignment of a new value to
the target."
I try it using the following code:
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
int i = 10, i1 = 20;
int &ri = i;
ri = i1;
cout << "ri:" <<ri<<" i:"<<i<< endl; //LINE1
B b; C c;
A a;
A* pa1 = &b;
//b.f(); //LINE2
pa1->f(); //LINE3
A &aa = b;
aa.f();
cout << "###REFERENCE####" << endl;
aa = c;
The above line assigns c to aa, which is a reference to b. The function
to call is statically resolved, so the above is equivalent to:
b.A::operator=(static_cast<A&>(c));
That assigns the A subobject of c to the A subobject of b - this is
called "slicing".
aa.f(); //LINE4
The dynamic type of b cannot be changed by an assignment, and hence that
still calls B::f.
// b.f() //LINE5
}
The output of LINE1 is---ri:20 i:20, so the textbook is correct.
The output of LINE4 is---Class A. And LINE5 can not compile (without
"//"), so b is not assigned the value c. This shows that the textbook
is wrong.
The textbook is correct. Examine this modification of your example to
see what's going on:
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
B b; C c;
A a;
b.A::f();
b.A::operator=(c);
b.A::f(); //LINE4
}
By the way, LINE2 can not compile due to B::f(int). The output of LINE3
is---Class A, so A::f() is not hiden by B::f(int). Is this due to
dynamic binding?
A::f() is hidden by B::f(int), but it is not *overridden* by it.
Tom