Множественное наследование c ++ и указатели - PullRequest
0 голосов
/ 16 мая 2018

Наличие множественного наследования

class A{};
class B{};

class C: public A, public B{};

что происходит, когда я делаю

C *c = new C;
A *a = c;  
B *b = c;

A *a1 = new C;
B *b1 = new C;

Что происходит с первым экземпляром C?Привязывает ли C указатель типа A к объекту, поэтому A указывает только на часть C, которая содержит члены A?Если это так, как он узнает, когда наверх?Если C содержит часть A и часть B, а часть A начинается со смещением 0, как он узнает, какое смещение остановить?

Спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

Первый C ++ требует, чтобы все инструкции заканчивались точкой с запятой (;).

Теперь по вашим вопросам:

Что происходит с первым экземпляром C?

Ничего.A * a = c; фактически инициализирует указатель A *, указывающий на динамически размещенный объект *c C.Это правильное преобразование указателя, потому что C является подклассом A. На самом деле, это всего лишь основы полиморфизма.

Делает ли привязка C к указателю типа A разрезание объекта, поэтому A указывает только начасть C, которая содержит члены A?

Никаких срезов не происходит при преобразовании указателей.A a1 = *(static_cast<A *>(c)); действительно сгенерирует нарезанную копию, содержащую только часть А.

Если это так, как он узнает, когда наверх?

Как это подробно реализации.Компиляторы могут сделать это, потому что это указано в стандарте.Обычные реализации используют смещения в адресах объектов.

Если C содержит часть A и часть B, а часть A начинается со смещения 0, как он узнает, какое смещение остановить?

И здесь это деталь реализации.Но для обычных реализаций часть A заканчивается с начальным смещением + sizeof (A).

0 голосов
/ 16 мая 2018

Назначает ли C указатель типа A нарезать объект

Нет. При инициализации (или присваивании, но присваивании это не то, что делает ваш код) указатель не влияет на указанный объект.

так A указывает только на часть C, которая содержит членов A?

Это не следует из нарезки, поскольку этого не происходит, но да, a (который является именем переменной-указателя, а не A) действительно указывает на подобъект A внутри C объект. Объект A содержит только свои собственные члены.

как узнать, какое смещение остановить?

Компилятор знает, насколько большим должен быть объект, и определяет точный размер всех определенных типов. Так как решение принимал компилятор, он, конечно, знает, что решил.

0 голосов
/ 16 мая 2018

C, будучи потомком обоих, - это A, а - это B.Таким образом, когда вы отклоняете указатель, среза не происходит (почему бы это все равно?), Но указатель указывает на соответствующую часть объекта.Стандартной схемой будет что-л.как

 c -> +++++++++++++++++++++
      +        C          +
 a -> + +++++++++++++++++ +
      + +      A        + +
      + +++++++++++++++++ +
      +                   +
 b -> + +++++++++++++++++ +
      + +      B        + +
      + +++++++++++++++++ +
      +                   +
      +  C's own members  +
      +                   +
      +++++++++++++++++++++

Оба a и b указывают на соответствующие подобъекты.

Откуда он знает? - Ну, компилятор создает макеты памяти,он определенно знает, каким виртуальным адресам должны быть назначены указатели, и как увеличение / уменьшение равно смещению указателя.

Обратите внимание, что при использовании простого указателя на базу в качестве единственной (и владеющей) ссылки наобъект, вы должны объявить деструктор базы virtual, иначе вы не сможете должным образом уничтожить объект.

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