Этот вопрос касается не самого языка C++ (т. Е. Не о стандарте), а о том, как вызвать компилятор для реализации альтернативных схем для виртуальной функции.Альтернативные схемы для реализации vptr?
Общая схема реализации виртуальных функций - это указатель на таблицу указателей.
class Base {
private:
int m;
public:
virtual metha();
};
эквивалентно, скажем, C будет что-то вроде
struct Base {
void (**vtable)();
int m;
}
первый член обычно является указателем на список виртуальных функций и т.д. (кусок области в памяти, приложение имеет без контроля). И в большинстве случаев это зависит от размера указателя перед рассмотрением членов и т. Д. Таким образом, в 32-битной схеме адресации около 4 байт и т. Д. Если вы создали список из 40k полиморфных объектов в ваших приложениях, это примерно 40k x 4 байта = 160 Кбайт перед любыми переменными-членами и т. Д. Я также знаю, что это самая быстрая и распространенная реализация среди компиляторов C++.
Я знаю, что это осложняется множественным наследованием (особенно с виртуальными классами в них, то есть с бриллиантовой структурой и т. Д.).
Альтернативный способ сделать то же самое, чтобы иметь первую переменную как идентификатор индекса к таблице vptrs (что то же самое в C, как показано ниже)
struct Base {
char classid; // the classid here is an index into an array of vtables
int m;
}
Если общее количество классов в приложения менее 255 (включая все возможные экземпляры шаблонов и т. д.), тогда символ достаточно хорош, чтобы удерживать индекс, тем самым уменьшая размер всех полиморфных классов в приложении (я исключаю проблемы выравнивания и т. д.).
Мои вопросы: есть ли какой-либо переключатель в GNU C++, LLVM или любой другой компилятор для этого? или уменьшить размер полиморфных объектов?
Редактировать: Я понимаю, что проблемы с выравниванием отмечены. Кроме того, если это было в 64-битной системе (предполагая 64-битный vptr), каждый член полиморфного объекта стоимостью около 8 байтов, то стоимость vptr составляет 50% от объема памяти. Это в основном относится к малым полиморфизмам, созданным в массе, поэтому мне интересно, возможна ли эта схема по крайней мере для определенных виртуальных объектов, если не для всего приложения.
Элемент m, вероятно, все еще будет выровнен по границе DWORD, чтобы вы ничего не получили. – Henrik
Проблема с этой схемой, вероятно, будет связана с выравниванием. Здесь структура Base в вашем втором примере не будет (обычно) занимать 5 байтов, сохраняя 3 байта на объект. В любом случае m будет выравниваться на границе 4 байта, поэтому у вас будет 3 байта впустую пространства –
Я думаю, что этот метод реализации виртуальной таблицы почти универсален. Я, конечно, никогда не сталкивался с другим методом или с любыми вариантами в GCC или Visual C++, которые бы контролировали, как они были реализованы. –