Указатель на базовый класс для объекта производного
Почему указатель на базовый класс может хранить ссылку объекта производного класса? Ведь производный класс может хранить больше методов и полей, чем базовый, значит, должно быть наоборот?
Ответы (2 шт):
Так ведь логично. Через указатель на родителя можно обратиться к любому полю или методу родителя. Значит у того, на что он указывает, должны быть как минимум все эти методы/поля (и могут быть еще какие-то).
Хрустальный шар подсказывает, что непонятки возникли из-за возможности инициализировать или присвоить указателю на объект бозового класса указатель на объект дочернего класса. Однако в этом случае указатель на объект базового класса не будет хранить ссылку на объект дочернего класса, вместо этого он будет хранить указатель на объект базового класса, который является подобъектом объекта дочернего класса. Наглядный пример:
class A{ int x{}; };
class B{ int y{}; };
class C: public A, public B { int z{}; };
C c{};
C * p_c{&c};
A * p_a{p_c};
B * p_b{p_c};
p_a
указывает на объект A
, который идет в начале C
и поэтому хранит такой же адрес, как и p_c
. При этом p_b
указывает на объект B
, который идет в C
после A
и поэтому хранит адрес, отличающийся от p_c
А почему нельзя сделать наоборот?
Наоборот тоже можно сделать. Однако обратное преобразование допускается только в явном виде, ведь в случае преобразования указателя на объект дочернего класса компилятор точно знает, что в нем есть подобъект родительского, а в обратном случае - нет.
C * p_ca{static_cast<C *>(p_a)};
C * p_cb{static_cast<C *>(p_b)};
Для полиморфных классов с RTTI для тех же целей есть еще dynamic_cast
.