Почему указатель производного класса не может указывать на объект базового класса без приведения? - PullRequest
7 голосов
/ 17 марта 2012

Я видел несколько примеров типов домашних животных и собак для этого типа базового вопроса здесь и здесь , но они не имеют смысла для меня, вот почему.

Предположим, у нас есть следующая структура класса

class Pet {};
class Dog : public Pet {};

тогда следующее утверждение

a (Dog) is a (Pet)

может быть правдой в реальной жизни, , но НЕ верен в C ++ , по моему мнению. Просто посмотрите на логическое представление объекта Dog, это выглядит так:

enter image description here

Правильнее будет сказать

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 объект!

Совершенно очевидно, что здесь я упускаю ключевой момент, который перевернул бы все мои рассуждения с ног на голову. Подскажите, пожалуйста, что это?

Я считаю, что параллели с примерами из реального мира только усложняют ситуацию. Я бы предпочел понять это с точки зрения технических деталей. Спасибо!

Ответы [ 11 ]

0 голосов
/ 17 марта 2012

На английском языке вы можете попытаться выработать следующие утверждения: «Аспекты собаки, которые делают ее домашним животным, являются подмножеством всех аспектов собаки» и «набор всех сущностей, которые являются собаки являются подмножеством множества сущностей, которые являются домашними животными.

D, P такой, что D (x) => x & isin; Собака, P (x) => x & isin; Pet

D (x) => P (x)

(D (x) верно, если у x есть все аспекты собаки, так что это говорит о том, что аспекты вещи, которая является собакой, представляют собой супер-набор аспектов вещей, которые являются домашними животными - P (x) ) верно, если D (x) верно, но не обязательно наоборот)

собака & супе; Домашнее животное =>

& forall; х х & изин; Dog => x & isin; Домашние животные (каждая собака - домашнее животное)

Но если D (x) & экв .; х & изин; Собака, тогда это одно и то же утверждение.

То, что «аспекты Собаки, которые делают его домашним животным, являются подмножеством собаки в целом» равносильно тому, что «набор собак является подмножеством множества домашних животных»

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