Please tell me why the output is as below for the following program. I am not getting the virtual classes in c++. observe the below code:
class B
{
public:
B(char c = 'a') : m_c(c) {}
public:
char get_c() const { return m_c; }
void set_c(char c) { m_c = c; }
private:
char m_c;
};
class C: public B
{ };
class D: public B
{ };
class E
: public C
, public D
{ };
int main()
{
E e;
C &c = e;
D &d = e;
std::cout << c.get_c();
d.set_c('b');
std::cout << c.get_c() << std::endl;
return 0;
}
O/P: aa I expect output would be ab. What would be the reason for getting "aa"??
If i have c.set_c('b') instead of d.set_c('b') then I will get O/P : "ab", Here also, I am not getting why is it as such. Both c, d are referring to one object only.
class C:virtual public B{};
class D:virtual public B{};
If the class C, class D are inherited virtually from B, then O/P would always be "ab"
There are two copies of B
in E
, one via C
and one via D
. When you call d.set_c('b')
, you're modifying the m_c
in D
's B
. When you call c.get_c()
, you then get the m_c
in C
's B
, which hasn't changed.
When you make C
and D
inherit from B
virtually, it solves the problem, because then there's only one copy of B
in E
.
This is relevant: http://www.parashift.com/c++-faq/virtual-inheritance-where.html
consider class C : public B
and C* c = new C
then c
point to an storage that begin with a B
since C*
is also B*
. and this is true
for class D : public B
.
Now for class E : public C, public D
and E* e = new E()
. memory of e
is something like:
{| B of C | other members of C }{| B of D | other members of D}
as you can see in above case we have 2 instance of B
one for C
and another for D
and now it is obvious when you call ((D*)e)->set_c( 'b' )
you only change B
instance of D
and B
instance of C
will remain unchanged.
now when you say class C : public virtual B
, C++ share B
instance with any other class that virtually inherit from B
. so in this case e
is something like:
| shared B |
| C members | | D members |
and as you can see we have only one B
so calling ((C*)e)->set_c
and ((D*)e)->set_c
will both act on same B
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With