Using Reference with virtual method

Hi,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;

struct A
{
	virtual void f() { cout<<"A\n"; }
};
struct B : A
{
	void f() { cout<<"B\n"; }
};

int main()
{
	A a;
	B b;

	cout<<"Example 1\n";
	A& refA = a;
	refA.f();
	/*B& refB = b;
	refB.f();*/

	cout<<"Example 2\n";
	refA = b;
	refA.f();

	cout<<"Example 3\n";
	A& otherRefA = b;
	otherRefA.f();
}


The output for this code is :

Example 1
A
Example 2
A
Example 3
B
Press any key to continue . . .

I would expect that both examples 2 & 3 will give me the same result.
I tried to figure it out but I could not.
Both are references of a base class type, that get a derived object.
Q1 : why is the difference between them ?

As I see it, its kind of a mix between pointer - which in case of virtual method that was override in derived class - would give me the derived method (e.g. "B")
and between regular object - which in case of virtual method that was override - would give me the specific method (Still "B").
So, example 2 "use" it as a regular object and example 3, "use" it as pointer.
Q2 : How should I refer to it ?

I am using VS2008.

Thanks
You can't rebind a reference.
refA = b; is using the assignment operator, would be equivalent to a = b;
Hi again
I still didn't get it...

What that it mean I can't rebind it ?

What actually happened in this line : refA = b; ?

you said a = b, so a got its derived object - so why b->f() does not activate ?

Thanks


he/she means that you cannot re-assign a reference, you must assign it at initialisation.
you said a = b, so a got its derived object

It didn't. The expression a = b (or refA = b, same thing) doesn't change the type of the object a, it's still A, and a.f() (or refA.f(), same thing) still calls A::f().
What actually happened in this line : refA = b; ?
it actually copies the data from the A part of B to the object a.

If A had a member i and B a member j, only the member i would have been copied
Let consider statement

refA = b;

it is equivalent to

refA.operator =( b );

However in struct A there is no such an assignment operator that assigns an object of type struct B to an object of type struct A.

The compiler implicitly created the following copy assignment operator

A & operator =( const A & );

So struct A has only this copy assignment operator. But you are trying in fact to use the following copy assignment operator

A & operator =( const B & );

There is no such a copy assignment operattor. So the compiler will try to apply the copy assignment operator that it created implicitly that is the operator shown above

A & operator =( const A & );

In this case it will convert the operand from type B to A and apply the operator. As you see the return type of the operator is A &
So refA will refer to an object of type A as before.
That is in fact object 'b' converted to type struct A will be assigned to object 'a'. refA always will refer to 'a'. You can not to change refA such a way that it would refer some other object. A reference can refer only one object that is specified when the reference is declared.
Last edited on
Ok, thanks, I got your point except one thing which end filling my puzzle...

I understand that "A reference can refer only one object that is specified when the reference is declared" as Vlad said.

so it make sense that at example 2 "A" would be printed. and you also explained it very well using the operator "=".

but what about example 3 ?
It declared to reference b object from the start, so "B" would be printed as you explained.

But what about the operator "=" there at example 3?
Can I assume that in that case, the compiler implicitly created the following copy assignment operator :

A & operator =( const B & );
and not
A & operator =( const A & );

I must say that you are great !!! Thanks :-)l
But what about the operator "=" there at example 3?

If you are referring to the statement A& otherRefA = b;, it does not involve operator= because it's not an assignment. It is reference initialization: http://en.cppreference.com/w/cpp/language/reference_initialization
Last edited on
In example 3 the copy assignment operator is not used,

A& otherRefA = b;

It is a declaration in which declared reference otherRefA is initialized by referencing object 'b'. References shall be initialized when they are declared.
Now it's all clear !!
Thanks :-)
If it helps, I recommend never using the = sign for declarations/initializations. Use the constructor syntax or C++11 initializer list syntax:
1
2
3
4
int x1 (4);
int x2 {7};
int &y {x1};
int &z (x2);
It doesn't matter in some cases whether you use () or {}, but I recommend you prefer to use {} because sometimes the compiler can think that () is a function declaration.
Topic archived. No new replies allowed.