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

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

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

  A
 / \
B   C
 \ /
  D

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

A   A
|   |
B   C
 \ /
  D

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

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

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

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

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

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

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

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

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

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

Заключение

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

c++

virtual-inheritance

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

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