Почему мы можем сделать: Base * base = new Derived; пока мы не можем сделать Derived * производная = новая база? - PullRequest
0 голосов
/ 18 апреля 2020

Теперь предположим, что базовый класс содержит некоторые функции, а производный класс явно наследуется от базового класса ... поэтому производный класс содержит функции из базового класса плюс несколько дополнительных собственных функций. следовательно, мы не должны быть в состоянии сделать Base *base = new Derived;, потому что производный имеет больше функций, чем базовый, поэтому базовый указатель на производный член не должен быть возможным, потому что он не сможет вызывать эти дополнительные производные функции. с другой стороны, Derived *derived = new Base следует разрешить, потому что производный указатель может содержать все функции базы без потери данных, верно? потом опять почему мы можем сделать: Base * base = new Derived; пока мы не можем сделать Derived * производная = новая база?

Ответы [ 2 ]

2 голосов
/ 18 апреля 2020

Любой Derived - это a Base, но Base - это не Derived.

Если у вас есть базовый класс, такой как Animal, хорошо иметь указатель на такое, инициализированный производным классом Human - человек может делать все вещи животного происхождения. Это является животным.

Но вы не можете инициализировать указатель на Человека только с животным, поскольку, когда мы попытаемся использовать его как человека, он потеряет все человеческие биты, так как он был создан только как базовое животное.

1 голос
/ 18 апреля 2020

Джеспер уже хорошо ответил на вопрос, но я подумал, что смогу предоставить контекст, ответив на ваш конкретный c пример

Derived *derived = new Base

, а затем вы скажете: «это следует разрешить, поскольку производный указатель может содержать все функции из базы без какой-либо потери данных, верно? "

это правда, что если бы вы вызвали derived->SomeBaseMethod() вещи могли работать (теоретически), но что должно произойти, если вы попытались вызвать какой-то метод, который существовал только на Derived? derived->SomeDerivedMethod(). Поскольку фактический тип, на который указывает указатель, является объектом Base, не будет производного метода для выполнения.

Теперь, если у вас есть Base* b = new Derived, то компилятор позволит вам вызывать base методы только на b (который будет определен для всех Derived объектов), но не позволит вам вызывать какие-либо производные методы, поскольку тип b равен base. Следовательно, это будет безопасно, тогда как Derived* d = new Base не будет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...