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