Накладные расходы на наследование С++ без виртуальных функций
В С++ какие служебные данные (память/процессор) связаны с наследованием базового класса, который не имеет виртуальных функций? Это так же хорошо, как прямая копия + вставка членов класса?
class a
{
public:
void get();
protected:
int _px;
}
class b : public a
{
}
по сравнению с
class a
{
public:
void get();
protected:
int _px;
}
class b
{
public:
void get();
protected:
int _px;
}
Ответы
Ответ 1
При использовании наследования по сравнению с копией и прошлым могут возникнуть небольшие издержки памяти (из-за заполнения), рассмотрите следующие определения классов:
struct A
{
int i;
char c1;
};
struct B1 : A
{
char c2;
};
struct B2
{
int i;
char c1;
char c2;
};
sizeof (B1), вероятно, будет 12, тогда как sizeof (B2) может быть просто 8. Это связано с тем, что базовый класс A дополняется отдельно до 8 байтов, а затем B1 снова заполняется до 12 байтов.
Ответ 2
Для компиляции потребуется немного больше времени, и дополнительных затрат времени выполнения не будет. С точки зрения оптимизатора не виртуальные методы такие же, как и процедуры - их можно вызывать, используя только их адрес памяти, без накладных расходов из таблицы виртуальных методов.
Ответ 3
Если вы забудете виртуальное наследование, наличие базового класса эквивалентно памяти и производительности, то есть иметь член того же класса. Исключено, что иногда это может быть даже лучше (например, пустой класс имеет размер как минимум один, но с пустым базовым классом часто может не иметь накладных расходов).
Ответ 4
Если у вас может быть указатель типа Base *, который указывает на объект типа Derived *, вам, вероятно, нужен виртуальный деструктор, и ваше исходное помещение больше не применяется. Если производный класс имеет пустой деструктор, и у него нет членов или все типы POD, вы можете уйти без виртуального деструктора, но обычно лучше играть в него безопасно и сделать его виртуальным с самого начала.
Компилятор будет генерировать прямой вызов кода, реализующего каждую не виртуальную функцию-член, поэтому нет накладных расходов.
Ответ 5
На самом деле, он не только увеличил память базовым классом. Подробнее о здесь в С++ FAQ