Что такое виртуальный базовый класс в С++?

О структуре памяти

Кстати, проблема с Dreaded virtual-inheritance Diamond заключается в том, что c++ базовый класс присутствует c++ несколько раз. Таким образом, при virtual-inheritance обычном наследовании вы считаете, что virtual-inheritance имеете:

  A
 / \
B   C
 \ /
  D

Но в схеме памяти c++ у вас есть:

A   A
|   |
B   C
 \ /
  D

Это объясняет, почему virtual-inheritance при вызове D::foo() возникает проблема cpp неоднозначности. Но реальная проблема c++ возникает, когда вы хотите cpp использовать переменную-член cxx A. Например, допустим, у нас cxx есть:

class A
{
    public :
       foo() ;
       int m_iValue ;
} ;

Когда вы попытаетесь cpp получить доступ к m_iValue из D, компилятор virtual-inheritance будет протестовать, потому virtual-inheritance что в иерархии он увидит cxx два m_iValue, а не один. И если вы c++ измените один, скажем, B::m_iValue (то cpp есть A::m_iValue родитель B), C::m_iValue не будет c++ изменен (то есть A::m_iValue родитель cxx C).

Здесь пригодится виртуальное c++ наследование, так как с ним virtual-inheritance вы вернетесь к истинному cpp ромбовидному макету, используя cxx не только один метод foo(), но cxx и один-единственный метод virtual-inheritance m_iValue.

Что может пойти не так?

Представьте:

  • A имеет базовую функцию.
  • B добавляет в него какой-то прикольный массив данных (например)
  • C добавляет к нему какую-нибудь интересную функцию, например шаблон наблюдателя (например, на m_iValue).
  • D наследуется от B и C и, таким образом, от A.

При нормальном cxx наследовании изменение m_iValue из cxx D неоднозначно, и это необходимо cpp разрешить. Даже если это cxx так, внутри D есть два m_iValues, так cxx что вам лучше помнить об c++ этом и обновлять их одновременно.

При virtual-inheritance виртуальном наследовании c++ изменение m_iValue из D допустимо... Но... Допустим, у c++ вас есть D. Через его интерфейс c++ C вы прикрепили наблюдателя. А virtual-inheritance через его интерфейс B вы обновляете cpp крутой массив, побочным эффектом c++ которого является прямое cpp изменение m_iValue...

Поскольку изменение virtual-inheritance m_iValue выполняется напрямую (без cpp использования виртуального cpp метода доступа), наблюдатель, «прослушивающий» через cpp C, не будет вызываться, поскольку c++ код, реализующий прослушивание, находится virtual-inheritance в C, а B не знает об этом...

Заключение

Если cpp у вас есть ромб в вашей иерархии, это virtual-inheritance означает, что вы с вероятностью c++ 95% сделали что-то не так cxx с указанной иерархией.

c++

virtual-inheritance

2022-10-18T11:22:54+00:00
Вопросы с похожей тематикой, как у вопроса:

Что такое виртуальный базовый класс в С++?