Size of the classes in case of virtual inheritance(C++) - c++

I saw this question.
this post is so old. so i got different output.
👇 test code
#include <iostream>
class M{
char k[ 3 ];
public:
void m(){};
};
class A{
char k[ 3 ];
public:
virtual void a(){};
};
class B : public A{
char j[ 3 ];
public:
virtual void b(){};
};
class C : public virtual A{
char i[ 3 ];
public:
virtual void c(){};
};
class D : public B, public C{
char h[ 3 ];
public:
virtual void d(){};
};
int main(){
A a;
B b;
C c;
D d;
std::cout << sizeof(M) << std::endl;
std::cout << sizeof(a) << std::endl;
std::cout << sizeof(b) << std::endl;
std::cout << sizeof(c) << std::endl;
std::cout << sizeof(d) << std::endl;
}
👇 and output
3
16
16
32
48
I understand why B have same size as A with this post.
But still i dont get it why C's size is 32.
C has subobject of A(16) + new array(3) + pointer to A(8)
and maybe padding(5).
It makes sense if B didn't reuse the padding, but it doesn't make sense because I thought B was the same size as A because he reused it.
I don't understand that result.
can you help me to get it?!
I search some other post..

Related

Why does `this` have different addresses in subclasses?

Why does the d instance have different this addresses? Someone told me that in OOP languages, a derived class is simply all the members of the base class, followed by members of its own.
#include <iostream>
#include <memory>
struct A
{
int member;
};
struct B : public virtual A
{
void print_b() { std::cout << static_cast<void*>(this) << " " << static_cast<void*>(&this->member) << std::endl; }
};
struct C : public virtual A
{
void print_c() { std::cout << static_cast<void*>(this) << " " << static_cast<void*>(std::addressof(member)) << std::endl; }
};
struct D : public B, public C
{
void print()
{
print_b();
print_c();
}
};
int main()
{
D d;
d.print();
}
Online outputs:
0x700af9347b90 0x700af9347ba0
0x700af9347b98 0x700af9347ba0
Because the B and C base sub objects are distinct objects in relation to each other and cannot share an address.
Empty base sub objects could be exempted from the requirement of having a unique address, but B and C are not empty.

Something I can not figure out about Vtable and Vptr in Multiple Inheritance

The following code
class B
{
public:
void f1() {}
};
class C
{
public:
void f2() {}
};
class D : public B, public C
{
public:
virtual void f3() {}
};
int main()
{
cout << sizeof(B) << endl;
cout << sizeof(C) << endl;
cout << sizeof(D) << endl;
system("pause");
return 0;
}
gets a result 1 1 8.So why is 8 not 4(in my computer,a pointer takes 4 bytes)?
B,C do not have vptr, and when D has virtual members, D's Vptr is placed in the Vtable of the first inherited class which is B,since the following code
class B
{
public:
virtual void f1() {} //now is virtual
};
class C
{
public:
void f2() {}
};
class D : public B, public C
{
public:
virtual void f3() {}
};
int main()
{
cout << sizeof(B) << endl;
cout << sizeof(C) << endl;
cout << sizeof(D) << endl;
system("pause");
return 0;
}
gets a result 4,1,4. May somebody explain it to me, thanks a lot!

Addresses in C++ of diamond inherited classes

Can somebody explain me why the address of an object changes when I cast it to an other parent class type in an diamond inherited class structure?
See this example:
#include <iostream>
class A{
public:
A(){};
virtual int a(){
return 0;
};
};
class B: virtual public A{
public:
B(){};
};
class C: virtual public A{
public:
C(){};
};
class D: public B, public C{
public:
D(){};
};
int main(){
A* a = new D();
std::cout << "dynamic_cast<A*>: " << dynamic_cast<A*>(a) << std::endl;
std::cout << "dynamic_cast<B*>: " << dynamic_cast<B*>(a) << std::endl;
std::cout << "dynamic_cast<C*>: " << dynamic_cast<C*>(a) << std::endl;
std::cout << "dynamic_cast<D*>: " << dynamic_cast<D*>(a) << std::endl;
return 0;
}
The output is:
dynamic_cast<A*>: 0x11e3c20
dynamic_cast<B*>: 0x11e3c20
dynamic_cast<C*>: 0x11e3c28
dynamic_cast<D*>: 0x11e3c20

how to use the "sizeof" operator with "virtual" operator [duplicate]

There is such code:
#include <iostream>
class A{
int a;
int fun(){}
};
class B{
int a;
virtual int fun(){}
};
int main()
{
std::cout << sizeof(A) << " " << sizeof(B) << std::endl;
std::cin.get();
return 0;
}
The output is:
4 8
Why class B is 4 bytes bigger than class A?
Any class with a virtual function needs a pointer to the vtable for that class. Therefore, there is a hidden member that's the size of the pointer.
http://en.wikipedia.org/wiki/Virtual_method_table

class with virtual functions takes more space

There is such code:
#include <iostream>
class A{
int a;
int fun(){}
};
class B{
int a;
virtual int fun(){}
};
int main()
{
std::cout << sizeof(A) << " " << sizeof(B) << std::endl;
std::cin.get();
return 0;
}
The output is:
4 8
Why class B is 4 bytes bigger than class A?
Any class with a virtual function needs a pointer to the vtable for that class. Therefore, there is a hidden member that's the size of the pointer.
http://en.wikipedia.org/wiki/Virtual_method_table