Почему одного виртуального наследования недостаточно для решения проблемы страшного алмаза? - PullRequest
4 голосов
/ 08 июля 2011
struct B { int i; };
struct D1 : virtual B {};
struct D2 : B {};  // <-- not virtual
struct DD : D1, D2 {};

Кодировав выше, все равно компилятор требует, чтобы D2 также было virtual:

DD d;
d.i = 0; // error: request for member `i' is ambiguous

Что я не понимаю, так это то, что если вы предложили компилятору, что B равно virtual относительно DD (через D1), то почему оно все еще i неоднозначно?

(Если моя память работает правильно, старый VC ++ (в 2006 году) был достаточно способен разобрать это только с помощью одного virtual наследования)

Ответы [ 3 ]

7 голосов
/ 08 июля 2011

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   |
+--+-----+---+----+-------+
 |         |         ^
 +---------+---------|
2 голосов
/ 08 июля 2011

Стандарт требует, чтобы d.i в этом случае был неоднозначным. Раздел 10.1.6 ISO / IEC 14882: 2003 охватывает классы с виртуальными и не виртуальными базовыми классами заданного типа.

2 голосов
/ 08 июля 2011

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

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