B не виртуален по отношению к DD - он виртуален по отношению к D1.В момент создания D2 он содержит полную копию B. Итак, теперь DD имеет две реализации B: одну как часть D2, а другую в конце (указанную D1).И имея две копии i
, его использование действительно неоднозначно.
Если бы D2 также использовал виртуальное наследование, вместо того, чтобы содержать копию B, он содержал бы указатель на экземпляр B, которым D1также указав на, и DD содержал бы только один экземпляр B.
Я попытаюсь проиллюстрировать макеты памяти, надеюсь, что это правильно ...:
Ваш случай, содно виртуальное наследование и одно не виртуальное -
| D1 | D2 + B | B |
+--+-------+----------+---------+
| vptr to B ^
+-----------------------|
Наличие виртуального наследования D1 и D2 -
| D1 | D2 | B |
+--+-----+---+----+-------+
| | ^
+---------+---------|