В объектно-ориентированных языках есть два основных способа создания объектов, которые наследуются от другого: конкатенация и делегирование.Первый является самым популярным, второй используется в основанных на прототипах языках.
Конкатенация означает, что когда B наследуется от A, в объекте есть две части: в первой части объекта (издлина равна размеру A), атрибуты (переменные-члены / поля в C ++) для A live.В другой части, существуют любые атрибуты, которые B добавляет к объекту.Конструкторы для каждого задействованного класса (A и B) выполняются таким образом, что все части (все атрибуты) инициализируются правильно.
Хотя объект управляется как единое целое, вы можете указать его указателем класса A.В этом случае указатель позволяет только видеть первую часть, часть, относящуюся к классу A (то есть его атрибутам), но не атрибуты из B, поскольку указатель может только видеть от начала к началу + размер класса A.
Скажем, класс A содержит целое число x:
class A {
public: int x;
};
, а B содержит целое число y:
class B: public A {
public: int y;
} obB;
Это означает, что объект класса B будет иметь длину 8 байтов (для 32 бит), длину x плюс длину y, а длина A составляет всего 4 байта, длину x.Указатель класса A на objB
:
A * ptrA = &objB;
будет только видеть x
,
cout << ptrA->x << endl;
cout << ptrA->y << endl; // ERROR
, а указатель на B:
B * ptrB = &objB;
будет иметь доступ к обоим x и y:
cout << ptrB->x << ',' << ptrB->y << endl;
Чтобы полностью это понять, вам нужно знать, что ptrB->y
примерно переведено в *( ( (int *) ptrB ) + 1 )
, ноэто другая история.
Надеюсь, это поможет.