where did my 4 bytes go? - c++

#include <iostream>
#include <cstdlib>
using std::cout;
class A
{
public :
A() { cout << "A()" << this << "\n";}
~A() { cout << "~A()" << this << "\n";}
//void func() { }
virtual void debug(int a) { cout << "A::debug";}
private :
int a;
};
class A1 : public A
{
public :
A1() { cout << "A1()"<< this << "\n";}
~A1() { cout << "~A1()"<< this << "\n";}
private :
int a1;
};
class A2 : public A
{
public :
A2() { cout << "A2()"<< this << "\n";}
~A2() { cout << "~A2()"<< this << "\n";}
private :
int a2;
};
class B : public A1, public A2
{
public :
B() { cout << "B()"<< this << "\n";}
~B() { cout << "~B()"<< this << "\n";}
void debug() { cout << "B::debug()"; }
private :
int a3;
};
int main()
{
cout << "sizeof(int)" << sizeof(int) << "\n";
cout << "sizeof(void*)" << sizeof(void*) << "\n";
cout << "sizeof(A): " << sizeof(A) << "\n";
cout << "sizeof(A1): " << sizeof(A1) << "\n";
cout << "sizeof(A2): " << sizeof(A2) << "\n";
cout << "sizeof(B): " << sizeof(B) << "\n";
B b;
b.debug();
}
output :
sizeof(int)4
sizeof(void*)4
sizeof(A): 8
sizeof(A1): 12
sizeof(A2): 12
**sizeof(B): 28**
A()0x28fef4
A1()0x28fef4
**A()0x28ff00**
A2()0x28ff00
B()0x28fef4
B::debug()~B()0x28fef4
~A2()0x28ff00
~A()0x28ff00
~A1()0x28fef4
~A()0x28fef4
Both A1 and A2 are 4(vtbl) + 4(A'sint) + 4(respective int) = 12 bytes but B is 28 bytes
I know its not guaranteed but what could be the possible use of those 4 bytes...I dont see any padding issues ? Can anyone point out what am I missing ?

sizeof(A): 8
The type A has a member of type int which in your platform is 4 bytes. It also has a virtual function, which means that a vptr (virtual table pointer) is allocated for each object of your class, the size of it is another 4 bytes.
**sizeof(B): 28**
B contains one object of type A1 (12 bytes), and an object of type A2 (another 12 bytes) and it adds another int for a total of 12+12+4 = 28 bytes. This is quite straightforward.

machine word size alignment of data items within structures.
See structure packing for more information.

Multiple inheritance will produce implementation-specific memory layouts of possibly different sizes.
Virtual tables and virtual pointers for multiple virtual inheritance and type casting

Related

I can't access to the protected member of my base class

I am new at programming using c++ and having some troubles creating my constructors & objects.
How can I access to my protected members like int p_iID in the Fahrzeug class?
I have to access them for both of my objects seperately.
I would be so happy if you could help me out with this.
class Fahrzeug {
private:
protected:
string p_sName;
int p_iID;
double p_dMaxGeschwindigkeit;
double p_dGesamtStrecke;
double p_dGesamtZeit;
double p_dZeit;
public:
virtual void vAusgeben(Fahrzeug* pFahrzeug1,Fahrzeug* pFahrzeug2);
virtual void vKopf();
virtual void vSimulieren(Fahrzeug *pFahrzeug, Fahrzeug *pFahrzeug2);
class PKW;
class PKW: public Fahrzeug{
PKW(const int p_iMaxID, string p_sName, double p_dMaxGeschwindigkeit, double p_dGesamtStrecke) {
p_iID = p_iMaxID;
this->p_sName = p_sName;
this->p_dMaxGeschwindigkeit = (p_dMaxGeschwindigkeit < 0) ? 0 : p_dMaxGeschwindigkeit;
this->p_dGesamtStrecke = p_dGesamtStrecke;
}
void vAusgeben(PKW pkw1, PKW pkw2) {
cout << "\n";
PKW pkw1;
PKW pkw2;
pkw1.vKopf();
cout << setw(5) << left << pkw1.p_iID<< " " << setw(10) <<pkw1.p_sName << setw(8) << " " << setw(15) << showpoint << pkw1.p_dMaxGeschwindigkeit << setw(3) << " " << pkw1.p_dGesamtStrecke; //Here I have the issue with pkw1.p_sName
cout << "\n";
cout << setw(5) << left << pkw2.p_iID << " " << setw(10) << pkw2.p_sName << setw(8) << " " << setw(15) << showpoint << pkw2.p_dMaxGeschwindigkeit << setw(3) << " " << pkw2.p_dGesamtStrecke;
cout << "\n";
}
}
void vAusgeben(PKW pkw1, PKW pkw2) {
You probably don't want to pass your PKW objects by value (or expect object slicing). Pass const references instead:
void vAusgeben(const PKW& pkw1, const PKW& pkw2) {
Also, why are you shadowing your 2 parameters with these local variables?
PKW pkw1; // ???
PKW pkw2; // ???
Aside from the issues raised in comments (and in another answer), there's a special rule for protected members that sometimes surprises people. An object of a derived type can access protected members of its base sub-object, but it can't access protected members of some other object. So:
struct B {
protected:
int i;
};
struct D : B {
void f(const B&);
};
void D::f(const B& b) {
i = 3; // okay, accessing my own protected member
b.i = 3; // no, access to protected member of different object not allowed
}
In the code in the question, the function PKW::vAusgeben can access its own copies of p_sName, p_dMaxGeschwindigkeit, and p_dGesamtStrecke, but it can't access pkw1.p_sName, pkw1.p_dMaxGeschwindigkeit, or pkw1.p_dGesamtStrecke.

C++ overwriting data from parent structure is not working

Normally it has no sense and is very unsafe, but only theoretically if there is a way,
Here is example:
#include<iostream>
struct A {
uint32_t &get() {
return *reinterpret_cast<uint32_t *>(this);
}
void set(const uint32_t val) {
*this = *reinterpret_cast<const A *>(&val);
}
};
struct B : A {
uint16_t a;
uint16_t b;
void set_b(const uint32_t val) {
*this = *reinterpret_cast<const B *>(&val);
}
};
main() {
B k;
k.a = 0x1234;
k.b = 0x5678;
std::cout << std::hex << k.get() << " : " << k.a << " " << k.b << std::endl;
k.set_b(0x87654321);
std::cout << std::hex << k.get() << " : " << k.a << " " << k.b << std::endl;
k.set(0xaabbccdd);
std::cout << std::hex << k.get() << " : " << k.a << " " << k.b << std::endl;
}
I get this result:
56781234 : 1234 5678
87654321 : 4321 8765
87654321 : 4321 8765
But I except that last should be:
aabbccdd : ccdd aabb
So, why overwriting data in structure from parent not working?
Experiment:
I make one experiment, that I add one variable into struct A, then set function was working as expected (but final structure was bigger)
Of course there exists different ways how to deal with this (for example with unions) but I only playing with this and I interested why this is not working.
In the class A the set function is really
void set(const uint32_t val) {
(*this).operator=(*reinterpret_cast<const A *>(&val));
}
That will invoke the automatically generated A::operator= function. But since A doesn't have any member variables to be copied, it does nothing.
And now that you've done your experiment, please don't do anything like that ever again.

why inherited functions changes the member variables in base class not the one of the same name of object called it

I want to ask why the setX function here sets the x member variable in class A not the member variable x in class D even though I call setX function through D object?
How does the compiler did that ?
#include<iostream>
using namespace std;
class A
{
public:
int x;
A() { cout << "A cons" << endl; }
void setX(int i){ x = i; cout << "setxA" << endl; }
void print() { cout << x; }
};
class B : public A
{
public:
int x =30;
B() { cout << "B cons" << endl; }
};
class D : public B {
public:
D() {
cout << "D cons" << endl;
}
void func() {
setX(10);
cout << x << endl;
cout << B::x << endl;
cout << A::x << endl;
}
};
int main()
{
D d;
d.func();
return 0;
}
the output from this code is
30
30
10
This is called name hiding. Both A and B have a member x and both members always exist (you just cannot access them the same way). A knows about his member x and so the setX function sets exactly this member A::x. In B, you define another x which hides A::x. This means that if you do
B obj;
obj.x = 10;
or
D obj;
obj.x = 10;
you will access B::x both of the times (because B is lower in the inheritance hierarchy and therefore hides A::x).
Here is an example of how you can still access A::x using different casts.
#include <iostream>
struct A {
int x = 0;
void setX(int i) { x = i; }
};
struct B : A {
int x = 20;
};
int main()
{
B obj;
A castToA = static_cast<A>(obj);
A* castToAPtr = reinterpret_cast<A*>(&obj);
std::cout
<< "access via B: " << obj.x << "\n"
<< "access via A: " << castToA.x << "\n"
<< "access via A*: " << castToAPtr->x << "\n"
<< "access via B::(A::x): " << obj.A::x << "\n\n";
obj.setX(100);
std::cout << "set x to 100\n\n";
std::cout
<< "access via B: " << obj.x << "\n"
<< "access via A: " << castToA.x << "\n"
<< "access via A*: " << castToAPtr->x << "\n"
<< "access via B::(A::x): " << obj.A::x << "\n\n";
return 0;
}
which yields the output:
access via B: 20
access via A: 0
access via A*: 0
access via B::A::x: 0
set x to 100
access via B: 20
access via A: 0
access via A*: 100
access via B::A::x: 100
Your class B has an x and also A has an X. As this, you have two x in B!
So you may remove the x from your B class?
If you need both, you can access them with
A::x or B::x inside a method of B which you already did.
So your D class have also both x and calling setX calls the setX method of A. As in D you see the x from B which hides your x from A everything works as expected.
Your method A::setX did not know that you derive later from it. If you want to override the method, B has define a own B::setX which will then also be used in D.
Example how to override a method and access the parameter in derived class:
class A
{
public:
int x; // A::x
int y = 40; // A::y
// this function only knows about A::x
void setX(int i){ x = i; cout << "setxA" << endl; }
void setY(int i){ y = i; cout << "setyA" << endl; }
};
class B : public A
{
public:
int x =30; // this x ( B::x) hide A::x
int y =50; // this y hides also A::y
// now we override setY from A ( hiding setY from A! )
void setY(int i){ y = i; cout << "setyB" << endl; }
};
class D : public B {
public:
void func() {
setX(10); // Calls A::setX, as A::setX only knows about
// A::x it will access A::x
cout << "X" << std::endl;
cout << x << endl;
cout << B::x << endl;
cout << A::x << endl;
setY(90);
cout << "Y" << std::endl;
cout << y << endl;
cout << B::y << endl;
cout << A::y << endl;
}
};
int main()
{
D d;
d.func();
return 0;
}

Size of class with virtual function adds extra 4 bytes

class NoVirtual {
int a;
public:
void x() const {}
int i() const { return 1; }
};
class OneVirtual {
int a;
public:
virtual void x() const {}
int i() const { return 1; }
};
class TwoVirtuals {
int a;
public:
virtual void x() const {}
virtual int i() const { return 1; }
};
int main() {
cout << "int: " << sizeof(int) << endl;
cout << "NoVirtual: "
<< sizeof(NoVirtual) << endl;
cout << "void* : " << sizeof(void*) << endl;
cout << "OneVirtual: "
<< sizeof(OneVirtual) << endl;
cout << "TwoVirtuals: "
<< sizeof(TwoVirtuals) << endl;
return 0;
}
The output is:
NoVirtual: 4
void* : 8
OneVirtual: 16
TwoVirtuals: 16
Question is:
Since OneVirtual and TwoVirtuals class have virtual function, size of class should be sizeof(int) + sizeof(void*) i.e. 12bytes. But size is printed as 16bytes.
Can someone explain why?
I assume you are compiling on 64bit machines since size of int is 4bytes.Typically for 64bit machines pointer size will be 8 bytes and int size is 4 bytes.To satisfy Data Alignment requirement to save read cycles
compiler adds extra 4 bytes(padding) hence result is 16bytes where as actual required size is 12 bytes.

How does g++ compiler know which vtable ptr to use if their are multiple vtable ptr in a base class?

I want to know know how does g++ compiler knows which table to use if their are multiple vtable present in a base class. Like the following example.
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
class sample1
{
private:
int b;
public:
sample1():b(34)
{
cout << "In sample1 constructor" << endl;
}
virtual void print_b()
{
cout << this->b << endl;
}
void print_all()
{
this->print_b();
}
void sample_print_()
{
//cout << this->a << "String : " << this->str1 << endl;
cout << "hello" << endl;
this->print_all();
}
};
class sample2
{
private:
int b1;
public:
sample2():b1(34)
{
cout << "In sample1 constructor" << endl;
}
virtual void print_b1()
{
cout << this->b1 << endl;
}
void print_all1()
{
this->print_b1();
}
};
class sample : public sample1 , public sample2
{
private:
int a;
char *str1;
public:
sample():a(12),sample1()
{
strcpy(this->str1,"hello world");
cout << "In Constructor" << endl;
}
~sample()
{
free(this->str1);
cout << "In Destructor" << endl;
}
void sample_print()
{
//cout << this->a << "String : " << this->str1 << endl;
cout << "hello" << endl;
this->print_all();
}
virtual void print_a()
{
cout << this->a <<endl;
}
};
In above example, child class sample has two parent classes sample1 and sample2 and each of these class have vtable of their own. What if i call a virtual function from sample(child class)? How does the compiler know, in which class that virtual function is present so that it call use that particular vtable pointer ? I know their will be two vtable pointer present in sample(child class) class , so how does compiler know which one to use ?