class A
{
int x;
public:
char y;
};
class B: public A
{
public:
int c;
};
int main ()
{
A a;
B b;
cout << "\na " << sizeof(a);
cout << "\nb " << sizeof(B);
return 0;
}
Now, the output is:
a 8
b 12
The problem is, shouldn't size of A be 5? 4 for int, and 1 for char.
And the size of B be 5 as well? 4 for int c, and 1 for char y?
The second doubt I had was, whether private members are inherited or not? The book I was using was inconsistent about it, and has mo confused.
Compilers round data allocation to a 32-bit boundary (usually). This is because the process of memory allocation is more efficient like this. This is why 5 bytes end up being 8.
Try using #pragma pack. I guess most compilers will respect the #pragma pack option.
And yes, private members will be there, just not directly accessible by the new class. But yes, those private members are there.
Why would B of size 5 ? Where would the value of x be stored ? It can't just magically be placed somewhere else. Accessibility is there for encapsulation, so a user who doesn't know how the class functions doesn't modify something which might cause undefined behavior. It doesn't isolate information after it is compiled because it doesn't matter once it is compiled, as it is a compile time problem.
Make int c; in class B a char c; and see what the output is.
This is because of the way the compiler aligns the data to improve speed because of how data is obtained from memory. On a 32-bit system it is only able to get 32-bits from memory per tick. So if the int isn't aligned on 32-bits it would take 2 ticks to get the same information.
If you make the data members protected instead of private then they can be accessed by the derived class.
However, this can be considered poor programming practice since it has some similarity to using globals - variables suddenly cropping up in the code and you can't see where they come from.
You can put getters and setters in the public area of the base class - or better have the base class actually provide some useful services.
In my view data in base classes is to be avoided - put it in the concrete derived classes - even if there is some repeated data definitions in different derived classes (within reason).
My question was not in what change needs to be done to make those members accessible.
I wanted to know, if they can't even be accessed, why inherit them. Will member functions defined the base class be able to access those members when derived to another class?
So is 12 bytes better than 9 bytes? Shouldn't they both take 2 ticks?
You aren't accessing the entire class as a whole, if you were to say have an array of B, if you were to do:
1 2 3 4 5 6 7 8 9
B arr[ 2 ];
sizeof( B ); // is 9 (assuming no alignment)
//assuming x is made public
arr[ 0 ].x // one tick, at address 0 (for examples sake, zero is valid)
arr[ 1 ].x // this would take two ticks as it is at address 9
// it will need to access the 32 bits at address 8 to get the first 3 bytes of c, then access address 12 to get the last byte