Попробуйте это:
package:
exclude:
- '*/**'
include:
- 'lib/**'
- '!./lib/dir/DirIdontWantBecauseTheSizeIsTooLarge'
- '!./lib/dir/DirButNotOneSubdir/DirIdontWantBecauseTheSizeIsTooLarge'
Он должен включать в себя все, что указано в lib/
, за исключением файлов, которые вы указали не делать. Используя !
, вы можете пометить файлы и каталоги, которые нужно пропустить на этапе включения.
Давайте посмотрим на расположение класса этих двух случаев.
Без виртуального у Вас есть два базовых класса ("X" и "Y") с целым числом каждый, и каждый из тех классов интегрировал в них "Основной" базовый класс, который также имеет целое число. Это - 4 целых числа, 32 бита каждый, в общей сложности Ваши 16 байтов.
Offset Size Type Scope Name
0 4 int Base a
4 4 int X x
8 4 int Base a
12 4 int Y y
16 size (Z members would come at the end)
(Редактирование: я записал программу в DJGPP для получения расположения и настроил таблицу для составления его.)
Теперь давайте говорить о виртуальных базовых классах: они заменяют фактический экземпляр класса с указателем на общий экземпляр. Ваш "Z" класс имеет только один "Основной" класс, и оба экземпляра "X" и "Y" указывают на него. Поэтому у Вас есть целые числа в X, Y, и Z, но у Вас только есть один Z. Это означает, что у Вас есть три целых числа, или 12 байтов. Но X и Y также имеют указатель на общий Z (иначе, они не знали бы, где найти его). На 32-разрядной машине два указателя добавят дополнительные 8 байтов. Это составляет 20, что Вы видите. Расположение памяти могло бы выглядеть примерно так (я не проверил его... ARM имеет пример, где упорядочивание X, Y, Z, затем Основа):
Offset Size Type Scope Name Value (sort of)
0 4 Base offset X ? 16 (or ptr to vtable)
4 4 int X x
8 4 Base offset Y ? 16 (or ptr to vtable)
12 4 int Y y
16 4 int Base a
20 size (Z members would come before the Base)
Таким образом, различием в памяти является комбинация двух вещей: один меньше целого числа и еще два указателя. Вопреки другому ответу я не полагаю, что vtables платят любой прямое (редактирование) (/, редактирование) сыплют это, так как нет никаких виртуальных функций.
Править: ppinsider предоставил больше информации о gcc случае, в котором он демонстрирует, что gcc реализует указатель на виртуальный базовый класс путем использования в других отношениях пустого vtable (т.е. никакие виртуальные функции). Тот путь, если бы были виртуальные функции, это не потребовало бы дополнительного указателя в экземпляре класса, требуя большей памяти. Я подозреваю, что оборотная сторона является дополнительной косвенностью для получения до базового класса.
Мы могли бы ожидать, что все компиляторы сделают это, но возможно нет. Страница 225 ARM обсуждает виртуальные базовые классы, не упоминая vtables. Страница 235 конкретно обращается "к виртуальным базовым классам с виртуальными функциями" и имеет схему, указывающую на расположение памяти, откуда существуют указатели частей X и Y, которые являются отдельными от указателей до vtable. Я советовал бы любому не брать для предоставленного, что указатель на Основу будет реализован с точки зрения таблицы.
Дополнительный размер, вероятно, из-за дополнительного VTables (http://en.wikipedia.org/wiki/Vtable), выделенный виртуальными классами и множественным наследованием.
Ответ Mark Santesson находится в значительной степени на деньгах, но assertation, что нет никаких vtables, является неправильным. Можно использовать g ++ - fdump-иерархия-классов для показа то, что продолжается. Вот не virtuals случай:
Class Base
size=4 align=4
base size=4 base align=4
Base (0x19a8400) 0
Class X
size=8 align=4
base size=8 base align=4
X (0x19a8440) 0
Base (0x19a8480) 0
Class Y
size=8 align=4
base size=8 base align=4
Y (0x19a84c0) 0
Base (0x19a8500) 0
Class Z
size=16 align=4
base size=16 base align=4
Z (0x19b1800) 0
X (0x19a8540) 0
Base (0x19a8580) 0
Y (0x19a85c0) 8
Base (0x19a8600) 8
Обратите особое внимание на "основной размер" аргумент. Теперь virtuals случай и показ только Z:
Class Z
size=20 align=4
base size=16 base align=4
Z (0x19b3000) 0
vptridx=0u vptr=((& Z::_ZTV1Z) + 12u)
X (0x19a8840) 0
primary-for Z (0x19b3000)
subvttidx=4u
Base (0x19a8880) 16 virtual
vbaseoffset=-0x0000000000000000c
Y (0x19a88c0) 8
subvttidx=8u vptridx=12u vptr=((& Z::_ZTV1Z) + 24u)
Base (0x19a8880) alternative-path
Обратите внимание, что "основной размер" является тем же, но "размер" является одним указателем больше, и обратите внимание, что существует теперь vtable указатель! Это в свою очередь содержит конструкцию vtables для родительских классов и всего волшебства межкласса (конструкция vtables и виртуальная таблица таблицы (VTT)), как описано здесь:
http://www.cse.wustl.edu/~mdeters/seminar/fall2005/mi.html
Обратите внимание, что фактическая функциональная vtable отправка будет пуста.