The following code shows the notorious diamond inheritance. But it seems that an appropriate reference designation avoids the ambiguity.
# include <iostream>
# include <stdio.h>
class B {
public:
int m_a ;
} ;
class D1 : public B { } ;
class D2 : public B { } ;
class E : public D1, public D2 { } ;
int main () {
E e ;
D1& c = e ;
D2& d = e ;
e.D1::m_a = 2 ;
e.D2::m_a = 2 ;
std::cout << c.m_a << std::endl ;
std::cout << d.m_a << std::endl ;
c.m_a = 3 ;
std::cout << c.m_a << std::endl ;
std::cout << d.m_a << std::endl ;
printf ( "%p\n", &c ) ;
printf ( "%p\n", &d ) ;
printf ( "%p\n", &e ) ;
printf ( "\n" ) ;
printf ("%p\n", (void*) &(c.m_a)) ;
printf ("%p\n", (void*) &(d.m_a)) ;
return 0 ;
}
The output is:
2
2
3
2
0xffffcbf0
0xffffcbf4
0xffffcbf0
0xffffcbf0
0xffffcbf4
So it seems that a reference 'knows' where it should start in the memory layout of the object 'e' which contains duplicated D1::m_a and D2::m_a . I wonder how it is achieved in C++ implementation. Thanks!
The easiest way to discover what's happening is by printing (void*)(&c)
and (void*)(&d)
. The two references refer to distinct subobjects of e
.
Also, the references to D1
and D2
do not know they're inside some E
. A reference can refer to any object in memory, but it doesn't know about the surroundings of that object.