Я видел несколько примеров типов домашних животных и собак для этого типа базового вопроса здесь и здесь , но они не имеют смысла для меня, вот почему.
Предположим, у нас есть следующая структура класса
class Pet {};
class Dog : public Pet {};
тогда следующее утверждение
a (Dog) is a (Pet)
может быть правдой в реальной жизни, , но НЕ верен в C ++ , по моему мнению. Просто посмотрите на логическое представление объекта Dog, это выглядит так:
![enter image description here](https://i.stack.imgur.com/GFtyR.png)
Правильнее будет сказать
a (Dog) has a (Pet)
или
a (Pet) is a subset of (Dog)
, который, если вы заметили, является логической противоположностью слова "собака - это животное"
Теперь проблема в том, что # 1 ниже разрешен, в то время как # 2 нет:
Pet* p = new Dog; // [1] - allowed!
Dog* d = new Pet; // [2] - not allowed without explicit casting!
Насколько я понимаю, [1]
не должно быть разрешено без предупреждений, потому что нет никакого способа, которым указатель должен указывать на объект типа его надмножества (объект Dog является надмножеством Pet) просто потому, что Pet не знает что-нибудь о новых членах, которые Dog мог объявить (подмножество Dog - Pet на диаграмме выше).
[1]
эквивалентен int*
, пытающемуся указать на double
объект!
Совершенно очевидно, что здесь я упускаю ключевой момент, который перевернул бы все мои рассуждения с ног на голову. Подскажите, пожалуйста, что это?
Я считаю, что параллели с примерами из реального мира только усложняют ситуацию. Я бы предпочел понять это с точки зрения технических деталей. Спасибо!