Reputation: 41
In the code, child
is casted to type Parent
, and passed to parentMove
. child
does not have members x
and y
. How does parentMove
access child.parent.x
and child.parent.y
? How does type casting work here? Thx
#include <stdio.h>
typedef struct{
int x, y;
int (*move)();
}Parent;
typedef struct {
Parent parent;
int h, w;
}Child;
int parentMove(Parent* parent, int y, int x){
parent->y+=y;
parent->x+=x;
printf("%d %d", parent->y, parent->x);
return 1;
}
int main(void) {
Parent parent = {.x = 2, .y = 1, .move = &parentMove};
Child child = {.parent = parent, .h = 3, .w = 4};
((Parent*)(&child))->move((Parent*)&child, 10, 10);
return 0;
}
Upvotes: 0
Views: 775
Reputation: 124
How does type casting work here?How does parentMove access child.parent.x and child.parent.y?
In child structure, the first member is the parent structure, so internally memory representation of child structure is --
{
{
int x; [ .. 4bytes .. ]
int y; [ .. 4bytes .. ]
int *move(); [ .. 4bytes .. ]
}
int h; [ .. 4bytes .. ]
int w; [ .. 4bytes .. ]
}
When you access parent.x , It is nothing but accessing first 4 bytes from starting address (i.e. &parent ). Similarly accessing parent.y means accessing 4 bytes after 4 bytes offset from starting address.
So when you pass address of child structure as a pointer to parent structure, the child-address actually points to a valid parent structure member inside, in the sense accessing first 4 bytes from the child-address is actually parent.x similarly other members of the contained parent structure are properly be accessed.
Upvotes: 0
Reputation: 213306
How does parentMove access child.parent.x and child.parent.y?
It doesn't know about the child part. It doesn't matter if a Parent object is declared as a stand-alone object or as a member of Child, same thing applies in either case.
How does type casting work here?
Poorly... you have implemented inheritance incorrectly if you have to cast to the base class from the caller side. It would seem that Child
should have implemented its own move
that takes a Child*
as parameter, if only to make it a wrapper to the parent.
Upvotes: 1