Размер самого производного класса в виртуальном наследовании - PullRequest
0 голосов
/ 03 октября 2019

В приведенном ниже коде, почему размер D равен 16 вместо 8 байтов?

Я думаю, потому что у нас есть виртуальный базовый класс , поэтому должен быть только один экземпляр A.

class A
{
public:
    int x_;
    int y_;
};

class B :  virtual public A
{
};

class C :  virtual public A
{

};

class D :  public B, public C
{
};

Ответы [ 2 ]

2 голосов
/ 03 октября 2019

В приведенном ниже коде почему размер D равен 16 вместо 8 байт?

В любом случае все эти производные классы не могут (практически (*)) иметь такой же размер, каких виртуальная база A:

  • отношение объекта производного класса к не виртуальному непосредственному базовому подобъекту, как и отношение с подобъектом-членом, отношение один к одному;
  • отношение объекта производного класса к виртуальному базовому подобъекту является отношением много к одному: по определению конкретный виртуальный базовый подобъект может быть прямой базой из нескольких производных классов. Здесь субобъект A является прямой базой подобъектов B и C объекта D (или подобъекта еще одного производного объекта).

(*) Iзнаю, что существуют возможные методы реализации, которые нарушают это утверждение, но они намного менее эффективны, неуклюжи и труднее сделать потокобезопасными, и даже менее эффективны в многопоточных программах.

Поскольку отношение много к одному,макет класса не может быть исправлен (в отличие от не виртуального члена или члена). Расположение уникального базового подобъекта зависит от точного созданного производного класса.

A (g) Значение класса X относится к экземпляру типа X или классу, производному от X;поэтому при использовании такого (g) lvalue, которое не ссылается на известный объект (при использовании имени локально объявленного объекта тип по определению известен), адрес базового подобъекта определяется во время выполнения от типа (или адреса)) информация, встроенная в экземпляр.

Таким образом, B и C должны нести такую ​​информацию для определения местоположения виртуальной базы. Это делает их больше, чем их база. Самому производному классу требуется место для информации о расположении во всех не виртуальных базах, плюс сама виртуальная база (обычно помещается в конце, если в ней есть какие-либо элементы данных).

2 голосов
/ 03 октября 2019

Я думаю, потому что у нас есть виртуальный базовый класс, поэтому должен быть только один экземпляр A.

Это правильно.

В приведенном ниже коде почемуразмер D равен 16 вместо 8 байт?

В моей системе D составляет 24 байта.

D содержит один подобъект B (исключая A), один подобъект C (исключая A) и один виртуальный подобъект A.

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

Более того (в зависимости от того, как реализованы виртуальные базы)вашим компилятором), виртуальное наследование требует использования виртуальной таблицы для доступа к виртуальной базе, поэтому экземпляр будет иметь виртуальный указатель на эту таблицу.

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