оптимизация — C ++ может (виртуальные) частные базовые классы быть удалены компилятором?

Учитывая следующий пример:

class A
{
protected:
static void useful_function_without_side_effects() {...}
}

class B : private A
{
// B has no friends :(

public:
void travel_back_in_time() { super_useful_function(); }
}

Вопрос 1: Будет ли разрешено компилятору оптимизировать базовый класс A, поскольку этот базовый класс не может реально влиять на B или на поведение во время выполнения каким-либо образом?

Вопрос 2: Изменится ли это, если наследование будет объявлено частным виртуальным, как это?

class B : private virtual A

2

Решение

Ответ 1:

Неполиморфные классы вообще не имеют никаких представителей во время выполнения. Единственные вещи, которые могут существовать, это объекты и методы, которые рассматриваются как функции. Класс только инструктирует компилятор получить доступ к частям объекта и разрешить вызов метода в соответствии с определением. После непосредственного разрешения все жестко закодировано в коде времени выполнения. private квалификатор здесь ничего не меняет.

Класс A (не имеющий полей), полученный из B, не «добавляет размер» к объекту класса B, если это ваш вопрос. Это всегда верно, если у класса A нет полей, но sizeof (A) всегда будет по крайней мере 1. Хотя также нет такого правила, что размер B должен быть суммой размеров всех полей и базовых классов.

Ответ 2

Это добавляет размер к классу B. Стандарт не уточняет, каким образом. В типичных реализациях он всегда будет увеличивать размер класса B на размер одного указателя плюс любой возможный размер класса A.

Обычно виртуальное наследование реализуется с использованием «указателя на себя». Таким образом, подобъект производного класса (A) физически является частью общего объекта, но к нему никогда не осуществляется прямой доступ, только через указатель на весь объект.

Это более-менее ситуация, когда у вас есть поля A и B без полей с полями общего размера 4:

Физическое наследство:

B: [A: 0] [B extension: 4]

Виртуальное наследование:

B: [A virtual: <pointer size>] [B extension: 4] [A shared subobject: 1]

Порядок этих вещей может отличаться в разных реализациях, хотя это часть определения ABI, а не частное правило компилятора (то есть все компиляторы на одной платформе должны использовать одни и те же правила).

1

Другие решения


По вопросам рекламы [email protected]